ACodec.cpp revision 1de1e25cba872bd4c077c2e394f8ca9c70b65856
127c174483a8ae9688d5d4897c19074f62c7f1701James Dong/*
227c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Copyright (C) 2010 The Android Open Source Project
327c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
427c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Licensed under the Apache License, Version 2.0 (the "License");
527c174483a8ae9688d5d4897c19074f62c7f1701James Dong * you may not use this file except in compliance with the License.
627c174483a8ae9688d5d4897c19074f62c7f1701James Dong * You may obtain a copy of the License at
727c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
827c174483a8ae9688d5d4897c19074f62c7f1701James Dong *      http://www.apache.org/licenses/LICENSE-2.0
927c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
1027c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Unless required by applicable law or agreed to in writing, software
1127c174483a8ae9688d5d4897c19074f62c7f1701James Dong * distributed under the License is distributed on an "AS IS" BASIS,
1227c174483a8ae9688d5d4897c19074f62c7f1701James Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1327c174483a8ae9688d5d4897c19074f62c7f1701James Dong * See the License for the specific language governing permissions and
1427c174483a8ae9688d5d4897c19074f62c7f1701James Dong * limitations under the License.
1527c174483a8ae9688d5d4897c19074f62c7f1701James Dong */
1627c174483a8ae9688d5d4897c19074f62c7f1701James Dong
17f933441648ef6a71dee783d733aac17b9508b452Andreas Huber//#define LOG_NDEBUG 0
18f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#define LOG_TAG "ACodec"
19f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
20f87e30fe71752dc431d8e8d5682c38271c03265aAndy Hung#ifdef __LP64__
21f87e30fe71752dc431d8e8d5682c38271c03265aAndy Hung#define OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
22f87e30fe71752dc431d8e8d5682c38271c03265aAndy Hung#endif
23f87e30fe71752dc431d8e8d5682c38271c03265aAndy Hung
24609b815a3131d22da38b2f452faa9f89daad4039Andy Hung#include <inttypes.h>
256fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar#include <utils/Trace.h>
266fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar
271de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar#include <gui/Surface.h>
281de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar
29f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/ACodec.h>
30f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <binder/MemoryDealer.h>
32f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/hexdump.h>
34f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ABuffer.h>
35f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ADebug.h>
36f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/AMessage.h>
37a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar#include <media/stagefright/foundation/AUtils.h>
38f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
397cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden#include <media/stagefright/BufferProducerWrapper.h>
40afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber#include <media/stagefright/MediaCodecList.h>
41f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaDefs.h>
42f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/OMXClient.h>
431065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber#include <media/stagefright/OMXCodec.h>
44f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
453a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber#include <media/hardware/HardwareAPI.h>
463a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
4797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu#include <OMX_AudioExt.h>
484154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev#include <OMX_VideoExt.h>
49f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <OMX_Component.h>
5097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu#include <OMX_IndexExt.h>
51f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
52496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#include "include/avc_utils.h"
53496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
54f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android {
55f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
56251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// OMX errors are directly mapped into status_t range if
57251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// there is no corresponding MediaError status code.
58251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Use the statusFromOMXError(int32_t omxError) function.
59251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung//
60251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Currently this is a direct map.
61251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// See frameworks/native/include/media/openmax/OMX_Core.h
62251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung//
63251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Vendor OMX errors     from 0x90000000 - 0x9000FFFF
64251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Extension OMX errors  from 0x8F000000 - 0x90000000
65251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Standard OMX errors   from 0x80001000 - 0x80001024 (0x80001024 current)
66251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung//
67251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
68251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// returns true if err is a recognized OMX error code.
69251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// as OMX error is OMX_S32, this is an int32_t type
70251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hungstatic inline bool isOMXError(int32_t err) {
71251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    return (ERROR_CODEC_MIN <= err && err <= ERROR_CODEC_MAX);
72251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung}
73251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
74251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// converts an OMX error to a status_t
75251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hungstatic inline status_t statusFromOMXError(int32_t omxError) {
76251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    switch (omxError) {
77251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case OMX_ErrorInvalidComponentName:
78251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case OMX_ErrorComponentNotFound:
79251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return NAME_NOT_FOUND; // can trigger illegal argument error for provided names.
80251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    default:
81251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return isOMXError(omxError) ? omxError : 0; // no translation required
82251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
83251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung}
84251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
85251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// checks and converts status_t to a non-side-effect status_t
86251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hungstatic inline status_t makeNoSideEffectStatus(status_t err) {
87251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    switch (err) {
88251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // the following errors have side effects and may come
89251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // from other code modules. Remap for safety reasons.
90251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case INVALID_OPERATION:
91251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case DEAD_OBJECT:
92251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return UNKNOWN_ERROR;
93251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    default:
94251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return err;
95251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
96251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung}
97251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
98f933441648ef6a71dee783d733aac17b9508b452Andreas Hubertemplate<class T>
99f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic void InitOMXParams(T *params) {
100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nSize = sizeof(T);
101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nVersionMajor = 1;
102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nVersionMinor = 0;
103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nRevision = 0;
104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nStep = 0;
105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
107f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct CodecObserver : public BnOMXObserver {
108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CodecObserver() {}
109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void setNotificationMessage(const sp<AMessage> &msg) {
111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mNotify = msg;
112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // from IOMXObserver
115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onMessage(const omx_message &omx_msg) {
116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> msg = mNotify->dup();
117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->setInt32("type", omx_msg.type);
119609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        msg->setInt32("node", omx_msg.node);
120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        switch (omx_msg.type) {
122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::EVENT:
123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("event", omx_msg.u.event_data.event);
125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("data1", omx_msg.u.event_data.data1);
126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("data2", omx_msg.u.event_data.data2);
127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::EMPTY_BUFFER_DONE:
131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
132609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                msg->setInt32("buffer", omx_msg.u.buffer_data.buffer);
133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::FILL_BUFFER_DONE:
137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
138609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                msg->setInt32(
139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "buffer", omx_msg.u.extended_buffer_data.buffer);
140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "range_offset",
142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.range_offset);
143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "range_length",
145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.range_length);
146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "flags",
148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.flags);
149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt64(
150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "timestamp",
151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.timestamp);
152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            default:
156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                TRESPASS();
157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->post();
161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
163f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual ~CodecObserver() {}
165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
166f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> mNotify;
168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(CodecObserver);
170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
174f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::BaseState : public AState {
175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState(ACodec *codec, const sp<AState> &parentState = NULL);
176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
177f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    enum PortMode {
179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        KEEP_BUFFERS,
180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        RESUBMIT_BUFFERS,
181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        FREE_BUFFERS,
182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ACodec *mCodec;
185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void postFillThisBuffer(BufferInfo *info);
196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
197f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXMessage(const sp<AMessage> &msg);
199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXEmptyBufferDone(IOMX::buffer_id bufferID);
201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXFillBufferDone(
203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID,
204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            size_t rangeOffset, size_t rangeLength,
205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            OMX_U32 flags,
206784e24e386b088c05d653ab482f2e95cb53e3d01Andy Hung            int64_t timeUs);
207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void getMoreInputDataIfPossible();
209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(BaseState);
211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
215ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberstruct ACodec::DeathNotifier : public IBinder::DeathRecipient {
216ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    DeathNotifier(const sp<AMessage> &notify)
217ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        : mNotify(notify) {
218ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
219ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
220ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual void binderDied(const wp<IBinder> &) {
221ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mNotify->post();
222ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
223ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
224ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprotected:
225ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual ~DeathNotifier() {}
226ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
227ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprivate:
228ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> mNotify;
229ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
230ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(DeathNotifier);
231ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber};
232ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
233f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::UninitializedState : public ACodec::BaseState {
234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    UninitializedState(ACodec *codec);
235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
236f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
238c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
240f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void onSetup(const sp<AMessage> &msg);
242c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onAllocateComponent(const sp<AMessage> &msg);
243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
244ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<DeathNotifier> mDeathNotifier;
245ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(UninitializedState);
247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
251c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberstruct ACodec::LoadedState : public ACodec::BaseState {
252c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    LoadedState(ACodec *codec);
253c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
254c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprotected:
255c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
256c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
257c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
258c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprivate:
259c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    friend struct ACodec::UninitializedState;
260c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
261c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onConfigureComponent(const sp<AMessage> &msg);
2627cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    void onCreateInputSurface(const sp<AMessage> &msg);
263c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onStart();
264c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onShutdown(bool keepComponentAllocated);
265c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
266c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedState);
267c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber};
268c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
269c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
270c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
271f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::LoadedToIdleState : public ACodec::BaseState {
272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    LoadedToIdleState(ACodec *codec);
273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
274f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
279f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t allocateBuffers();
281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedToIdleState);
283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
287f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToExecutingState : public ACodec::BaseState {
288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToExecutingState(ACodec *codec);
289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
290f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
295f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToExecutingState);
297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
301f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingState : public ACodec::BaseState {
302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingState(ACodec *codec);
303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
304054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitRegularOutputBuffers();
305054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitOutputMetaBuffers();
306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void submitOutputBuffers();
307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Submit output buffers to the decoder, submit input buffers to client
309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // to fill with data.
310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void resume();
311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
312349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    // Returns true iff input and output buffers are in play.
313349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool active() const { return mActive; }
314349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
315f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
322f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
323349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool mActive;
324349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingState);
326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
330f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::OutputPortSettingsChangedState : public ACodec::BaseState {
331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OutputPortSettingsChangedState(ACodec *codec);
332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
333f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
340f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(OutputPortSettingsChangedState);
342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
346f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingToIdleState : public ACodec::BaseState {
347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingToIdleState(ACodec *codec);
348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
349f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
358f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool mComponentNowIdle;
3625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingToIdleState);
364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
368f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToLoadedState : public ACodec::BaseState {
369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToLoadedState(ACodec *codec);
370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
371f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
377f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToLoadedState);
379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
383f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::FlushingState : public ACodec::BaseState {
384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    FlushingState(ACodec *codec);
385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
386f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
395f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool mFlushComplete[2];
397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(FlushingState);
401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
405f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ACodec()
406afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    : mQuirks(0),
407609b815a3131d22da38b2f452faa9f89daad4039Andy Hung      mNode(0),
4085778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mSentFormat(false),
4098db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu      mIsVideo(false),
410c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber      mIsEncoder(false),
411308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang      mUseMetadataOnEncoderOutput(false),
4129806555d3930be43e11106281dee354820ac1c88Andreas Huber      mShutdownInProgress(false),
41354b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar      mExplicitShutdown(false),
4149806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderDelay(0),
4159806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderPadding(0),
416e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang      mRotationDegrees(0),
4179806555d3930be43e11106281dee354820ac1c88Andreas Huber      mChannelMaskPresent(false),
418054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mChannelMask(0),
419054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mDequeueCounter(0),
420054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mStoreMetaDataInOutputBuffers(false),
421a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber      mMetaDataBuffersToSubmit(0),
42294ee4b708acfa941581160b267afb79192b1d816Chong Zhang      mRepeatFrameDelayUs(-1ll),
4232c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang      mMaxPtsGapUs(-1ll),
42437b2b389139ed638831e49708c947863eef631efRonghua Wu      mMaxFps(-1),
4252c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang      mTimePerFrameUs(-1ll),
426609b815a3131d22da38b2f452faa9f89daad4039Andy Hung      mTimePerCaptureUs(-1ll),
427ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad      mCreateInputBuffersSuspended(false),
428ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad      mTunneled(false) {
429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mUninitializedState = new UninitializedState(this);
430c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mLoadedState = new LoadedState(this);
431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mLoadedToIdleState = new LoadedToIdleState(this);
432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToExecutingState = new IdleToExecutingState(this);
433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingState = new ExecutingState(this);
434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOutputPortSettingsChangedState =
436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        new OutputPortSettingsChangedState(this);
437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingToIdleState = new ExecutingToIdleState(this);
439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToLoadedState = new IdleToLoadedState(this);
440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushingState = new FlushingState(this);
441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
443dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber    mInputEOSResult = OK;
444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeState(mUninitializedState);
446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
448f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::~ACodec() {
449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
451f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::setNotificationMessage(const sp<AMessage> &msg) {
452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mNotify = msg;
453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
455f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::initiateSetup(const sp<AMessage> &msg) {
456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setWhat(kWhatSetup);
4571d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    msg->setTarget(this);
458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
461a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Hubervoid ACodec::signalSetParameters(const sp<AMessage> &params) {
4621d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetParameters, this);
463a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->setMessage("params", params);
464a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->post();
465a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
466a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4675778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateAllocateComponent(const sp<AMessage> &msg) {
4685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatAllocateComponent);
4691d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    msg->setTarget(this);
4705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4715778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4735778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateConfigureComponent(const sp<AMessage> &msg) {
4745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatConfigureComponent);
4751d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    msg->setTarget(this);
4765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4775778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4797cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::initiateCreateInputSurface() {
4801d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatCreateInputSurface, this))->post();
4817cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
4827cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4837cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::signalEndOfInputStream() {
4841d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatSignalEndOfInputStream, this))->post();
4857cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
4867cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4875778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateStart() {
4881d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatStart, this))->post();
4895778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
491f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalFlush() {
4927a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] signalFlush", mComponentName.c_str());
4931d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatFlush, this))->post();
494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
496f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalResume() {
4971d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatResume, this))->post();
498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
500c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::initiateShutdown(bool keepComponentAllocated) {
5011d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatShutdown, this);
502c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->setInt32("keepComponentAllocated", keepComponentAllocated);
503c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->post();
50430358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar    if (!keepComponentAllocated) {
50530358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        // ensure shutdown completes in 3 seconds
5061d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar        (new AMessage(kWhatReleaseCodecInstance, this))->post(3000000);
50730358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar    }
508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
510496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubervoid ACodec::signalRequestIDRFrame() {
5111d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatRequestIDRFrame, this))->post();
512496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
513496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5144dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
5154dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// Some codecs may return input buffers before having them processed.
5164dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// This causes a halt if we already signaled an EOS on the input
5174dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// port.  For now keep submitting an output buffer if there was an
5184dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// EOS on the input port, but not yet on the output port.
5194dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnarvoid ACodec::signalSubmitOutputMetaDataBufferIfEOS_workaround() {
5204dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    if (mPortEOS[kPortIndexInput] && !mPortEOS[kPortIndexOutput] &&
5214dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            mMetaDataBuffersToSubmit > 0) {
5221d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar        (new AMessage(kWhatSubmitOutputMetaDataBufferIfEOS, this))->post();
5234dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    }
5244dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar}
5254dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
526f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mDealer[portIndex] == NULL);
530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mBuffers[portIndex].isEmpty());
531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
534054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (mStoreMetaDataInOutputBuffers) {
535054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputMetaDataBuffers();
536054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
537054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputBuffersFromNativeWindow();
538054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
5395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
5405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
5415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
5425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = portIndex;
543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
5455778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err == OK) {
548609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGV("[%s] Allocating %u buffers of size %u on %s port",
5495778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mComponentName.c_str(),
5505778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    def.nBufferCountActual, def.nBufferSize,
5515778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    portIndex == kPortIndexInput ? "input" : "output");
552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            size_t totalSize = def.nBufferCountActual * def.nBufferSize;
5545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
5575778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
5585778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(mem.get() != NULL);
559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
560ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                BufferInfo info;
561ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                info.mStatus = BufferInfo::OWNED_BY_US;
562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
563afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                uint32_t requiresAllocateBufferBit =
564afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                    (portIndex == kPortIndexInput)
565afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        ? OMXCodec::kRequiresAllocateBufferOnInputPorts
566afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        : OMXCodec::kRequiresAllocateBufferOnOutputPorts;
5671065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
568308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                if ((portIndex == kPortIndexInput && (mFlags & kFlagIsSecure))
569308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        || mUseMetadataOnEncoderOutput) {
570ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    mem.clear();
571ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
572ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    void *ptr;
573ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->allocateBuffer(
574ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, def.nBufferSize, &info.mBufferID,
575ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            &ptr);
576ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
577308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    int32_t bufSize = mUseMetadataOnEncoderOutput ?
578308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                            (4 + sizeof(buffer_handle_t)) : def.nBufferSize;
579308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
580308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    info.mData = new ABuffer(ptr, bufSize);
581ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                } else if (mQuirks & requiresAllocateBufferBit) {
5825778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    err = mOMX->allocateBufferWithBackup(
583ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, mem, &info.mBufferID);
5845778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
585ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->useBuffer(mNode, portIndex, mem, &info.mBufferID);
586ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                }
587ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
588ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                if (mem != NULL) {
589ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    info.mData = new ABuffer(mem->pointer(), def.nBufferSize);
5905778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
5911065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
5925778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mBuffers[portIndex].push(info);
5931065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            }
5941065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
5955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
5985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
5995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> notify = mNotify->dup();
602d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatBuffersAllocated);
6035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("portIndex", portIndex);
605eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
606eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    sp<PortDescription> desc = new PortDescription;
607eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
6085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
609eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        const BufferInfo &info = mBuffers[portIndex][i];
6105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
611eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        desc->addBuffer(info.mBufferID, info.mData);
612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
614eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    notify->setObject("portDesc", desc);
6155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->post();
6165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
620054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::configureOutputBuffersFromNativeWindow(
621054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 *bufferCount, OMX_U32 *bufferSize,
622054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 *minUndequeuedBuffers) {
623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = kPortIndexOutput;
626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
634ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    err = native_window_set_buffers_dimensions(
635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameWidth,
637ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar            def.format.video.nFrameHeight);
638ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar
639ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    if (err != 0) {
640ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        ALOGE("native_window_set_buffers_dimensions failed: %s (%d)",
641ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                strerror(-err), -err);
642ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        return err;
643ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    }
644ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar
645ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    err = native_window_set_buffers_format(
646ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar            mNativeWindow.get(),
647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.eColorFormat);
648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
650ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        ALOGE("native_window_set_buffers_format failed: %s (%d)",
651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                strerror(-err), -err);
652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
655e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang    if (mRotationDegrees != 0) {
656e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        uint32_t transform = 0;
657e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        switch (mRotationDegrees) {
658e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            case 0: transform = 0; break;
659e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            case 90: transform = HAL_TRANSFORM_ROT_90; break;
660e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            case 180: transform = HAL_TRANSFORM_ROT_180; break;
661e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            case 270: transform = HAL_TRANSFORM_ROT_270; break;
662e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            default: transform = 0; break;
663e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        }
664e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang
665e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        if (transform > 0) {
666e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            err = native_window_set_buffers_transform(
667e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang                    mNativeWindow.get(), transform);
668e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            if (err != 0) {
669e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang                ALOGE("native_window_set_buffers_transform failed: %s (%d)",
670e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang                        strerror(-err), -err);
671e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang                return err;
672e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            }
673e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        }
674e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang    }
675e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang
676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Set up the native window.
6773c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    OMX_U32 usage = 0;
6783c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
6793c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    if (err != 0) {
6805ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("querying usage flags from OMX IL component failed: %d", err);
6813c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        // XXX: Currently this error is logged, but not fatal.
6823c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        usage = 0;
6833c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    }
6845a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar    int omxUsage = usage;
6853c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis
6861713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang    if (mFlags & kFlagIsGrallocUsageProtected) {
687bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        usage |= GRALLOC_USAGE_PROTECTED;
688bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
689bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
690bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // Make sure to check whether either Stagefright or the video decoder
691bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // requested protected buffers.
692bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (usage & GRALLOC_USAGE_PROTECTED) {
693bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Verify that the ANativeWindow sends images directly to
694bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // SurfaceFlinger.
695bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        int queuesToNativeWindow = 0;
696bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->query(
697bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                mNativeWindow.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
698bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                &queuesToNativeWindow);
699bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != 0) {
700bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error authenticating native window: %d", err);
701bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
702bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
703bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (queuesToNativeWindow != 1) {
704bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("native window could not be authenticated");
705bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return PERMISSION_DENIED;
706bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
707bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
708bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
7095a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar    int consumerUsage = 0;
7105a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar    err = mNativeWindow->query(
7115a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            mNativeWindow.get(), NATIVE_WINDOW_CONSUMER_USAGE_BITS,
7125a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            &consumerUsage);
7135a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar    if (err != 0) {
7145a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        ALOGW("failed to get consumer usage bits. ignoring");
7155a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        err = 0;
7165a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar    }
7175a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
7185a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar    ALOGV("gralloc usage: %#x(OMX) => %#x(ACodec) + %#x(Consumer) = %#x",
7195a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            omxUsage, usage, consumerUsage, usage | consumerUsage);
7205a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar    usage |= consumerUsage;
721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_usage(
722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
7233c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis            usage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP);
724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
72629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err);
727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
730ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // Exits here for tunneled video playback codecs -- i.e. skips native window
731ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // buffer allocation step as this is managed by the tunneled OMX omponent
732ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // itself and explicitly sets def.nBufferCountActual to 0.
733ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    if (mTunneled) {
734ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        ALOGV("Tunneled Playback: skipping native window buffer allocation.");
735ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        def.nBufferCountActual = 0;
736ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        err = mOMX->setParameter(
737ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
738ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
739ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *minUndequeuedBuffers = 0;
740ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *bufferCount = 0;
741ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *bufferSize = 0;
742ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        return err;
743ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    }
744ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
745054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *minUndequeuedBuffers = 0;
746258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    err = mNativeWindow->query(
747258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
748054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (int *)minUndequeuedBuffers);
749258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
750258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    if (err != 0) {
75129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
752258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                strerror(-err), -err);
753258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        return err;
754258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
755258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
756e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // FIXME: assume that surface is controlled by app (native window
757e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // returns the number for the case when surface is not controlled by app)
7581faa41704e0b976e546321effcb09a85767d51baLajos Molnar    // FIXME2: This means that minUndeqeueudBufs can be 1 larger than reported
7591faa41704e0b976e546321effcb09a85767d51baLajos Molnar    // For now, try to allocate 1 more buffer, but don't fail if unsuccessful
760e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar
761e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // Use conservative allocation while also trying to reduce starvation
762e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //
763e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // 1. allocate at least nBufferCountMin + minUndequeuedBuffers - that is the
764e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //    minimum needed for the consumer to be able to work
765e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // 2. try to allocate two (2) additional buffers to reduce starvation from
766e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //    the consumer
7671faa41704e0b976e546321effcb09a85767d51baLajos Molnar    //    plus an extra buffer to account for incorrect minUndequeuedBufs
7681faa41704e0b976e546321effcb09a85767d51baLajos Molnar    for (OMX_U32 extraBuffers = 2 + 1; /* condition inside loop */; extraBuffers--) {
769e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        OMX_U32 newBufferCount =
770e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            def.nBufferCountMin + *minUndequeuedBuffers + extraBuffers;
771258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        def.nBufferCountActual = newBufferCount;
772258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        err = mOMX->setParameter(
773258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
774258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
775e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        if (err == OK) {
776e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            *minUndequeuedBuffers += extraBuffers;
777e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            break;
778e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        }
779e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar
780609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGW("[%s] setting nBufferCountActual to %u failed: %d",
781e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar                mComponentName.c_str(), newBufferCount, err);
782e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        /* exit condition */
783e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        if (extraBuffers == 0) {
784258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            return err;
785258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        }
786258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
787258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffer_count(
789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(), def.nBufferCountActual);
790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
79229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                -err);
794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
797054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferCount = def.nBufferCountActual;
798054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferSize =  def.nBufferSize;
799054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
800054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
801054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
802054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputBuffersFromNativeWindow() {
803054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
804054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
805054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
806054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
807054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
808e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    mNumUndequeuedBuffers = minUndequeuedBuffers;
809054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
8103298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia    if (!mStoreMetaDataInOutputBuffers) {
8113298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia        static_cast<Surface*>(mNativeWindow.get())
8123298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia                ->getIGraphicBufferProducer()->allowAllocation(true);
8133298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia    }
8143298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia
815609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Allocating %u buffers from a native window of size %u on "
816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         "output port",
817054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount, bufferSize);
818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Dequeue buffers and send them to OMX
820054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
8218ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev        ANativeWindowBuffer *buf;
8221e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
82429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
82974006804065941841883c4b46ee785070164023fJamie Gennis        BufferInfo info;
83074006804065941841883c4b46ee785070164023fJamie Gennis        info.mStatus = BufferInfo::OWNED_BY_US;
831054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(NULL /* data */, bufferSize /* capacity */);
83274006804065941841883c4b46ee785070164023fJamie Gennis        info.mGraphicBuffer = graphicBuffer;
83374006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].push(info);
83474006804065941841883c4b46ee785070164023fJamie Gennis
835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferId;
836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &bufferId);
838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
839609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGE("registering GraphicBuffer %u with OMX IL component failed: "
84074006804065941841883c4b46ee785070164023fJamie Gennis                 "%d", i, err);
841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
84474006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
84574006804065941841883c4b46ee785070164023fJamie Gennis
846609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGV("[%s] Registered graphic buffer with ID %u (pointer = %p)",
847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mComponentName.c_str(),
848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             bufferId, graphicBuffer.get());
849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
850f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelStart;
852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelEnd;
853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // If an error occurred while dequeuing we need to cancel any buffers
856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // that were dequeued.
857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelStart = 0;
85874006804065941841883c4b46ee785070164023fJamie Gennis        cancelEnd = mBuffers[kPortIndexOutput].size();
859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
860054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // Return the required minimum undequeued buffers to the native window.
861054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelStart = bufferCount - minUndequeuedBuffers;
862054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelEnd = bufferCount;
863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
8673fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        status_t error = cancelBufferToNativeWindow(info);
8683fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        if (err == 0) {
8693fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia            err = error;
8703fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        }
871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8733298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia    if (!mStoreMetaDataInOutputBuffers) {
8743298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia        static_cast<Surface*>(mNativeWindow.get())
8753298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia                ->getIGraphicBufferProducer()->allowAllocation(false);
8763298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia    }
8773298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia
878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
881054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputMetaDataBuffers() {
882054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
883054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
884054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
885054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
886054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
887e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    mNumUndequeuedBuffers = minUndequeuedBuffers;
888054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
889609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Allocating %u meta buffers on output port",
890054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount);
891054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
892054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    size_t totalSize = bufferCount * 8;
893054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mDealer[kPortIndexOutput] = new MemoryDealer(totalSize, "ACodec");
894054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
895054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // Dequeue buffers and send them to OMX
896054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
897054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo info;
898054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
899054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mGraphicBuffer = NULL;
900054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mDequeuedAt = mDequeueCounter;
901054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
902054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        sp<IMemory> mem = mDealer[kPortIndexOutput]->allocate(
903054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                sizeof(struct VideoDecoderOutputMetaData));
904054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(mem.get() != NULL);
905054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(mem->pointer(), mem->size());
906054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
907054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // we use useBuffer for metadata regardless of quirks
908054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        err = mOMX->useBuffer(
909054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mNode, kPortIndexOutput, mem, &info.mBufferID);
910054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
911054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        mBuffers[kPortIndexOutput].push(info);
912054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
913609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGV("[%s] allocated meta buffer with ID %u (pointer = %p)",
914054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mComponentName.c_str(), info.mBufferID, mem->pointer());
915054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
916054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
917054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mMetaDataBuffersToSubmit = bufferCount - minUndequeuedBuffers;
918054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
919054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
920054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
921054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::submitOutputMetaDataBuffer() {
922054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mStoreMetaDataInOutputBuffers);
923054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mMetaDataBuffersToSubmit == 0)
924054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return OK;
925054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
926054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *info = dequeueBufferFromNativeWindow();
927054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (info == NULL)
928054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return ERROR_IO;
929054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
930609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] submitting output meta buffer ID %u for graphic buffer %p",
931054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          mComponentName.c_str(), info->mBufferID, info->mGraphicBuffer.get());
932054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
933054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    --mMetaDataBuffersToSubmit;
934054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK_EQ(mOMX->fillBuffer(mNode, info->mBufferID),
935054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             (status_t)OK);
936054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
937054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
938054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return OK;
939054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
940054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
941f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
944609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Calling cancelBuffer on buffer %u",
945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mComponentName.c_str(), info->mBufferID);
946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int err = mNativeWindow->cancelBuffer(
9481e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        mNativeWindow.get(), info->mGraphicBuffer.get(), -1);
949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9503fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia    ALOGW_IF(err != 0, "[%s] can not return buffer %u to native window",
9513fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia            mComponentName.c_str(), info->mBufferID);
952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9553fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia    return err;
956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
958f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
9598ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev    ANativeWindowBuffer *buf;
960054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mNativeWindow.get() != NULL);
961ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
962ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    if (mTunneled) {
963ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        ALOGW("dequeueBufferFromNativeWindow() should not be called in tunnel"
964ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad              " video playback mode mode!");
965ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        return NULL;
966ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    }
967ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
9681e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    if (native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf) != 0) {
96929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("dequeueBuffer failed.");
970c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber        return NULL;
971c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
973054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *oldest = NULL;
974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
978054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mGraphicBuffer != NULL &&
979054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            info->mGraphicBuffer->handle == buf->handle) {
980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus,
981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (int)BufferInfo::OWNED_BY_NATIVE_WINDOW);
982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
987054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
988054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW &&
989054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (oldest == NULL ||
990054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             // avoid potential issues from counter rolling over
991054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mDequeueCounter - info->mDequeuedAt >
992054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    mDequeueCounter - oldest->mDequeuedAt)) {
993054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            oldest = info;
994054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
995054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
996054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
997054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (oldest) {
998054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(mStoreMetaDataInOutputBuffers);
999054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1000054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // discard buffer in LRU info and replace with new buffer
1001054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mGraphicBuffer = new GraphicBuffer(buf, false);
1002054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mStatus = BufferInfo::OWNED_BY_US;
1003054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1004d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        mOMX->updateGraphicBufferInMeta(
1005d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                mNode, kPortIndexOutput, oldest->mGraphicBuffer,
1006d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                oldest->mBufferID);
1007054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1008d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        VideoDecoderOutputMetaData *metaData =
1009d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar            reinterpret_cast<VideoDecoderOutputMetaData *>(
1010d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                    oldest->mData->base());
1011d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        CHECK_EQ(metaData->eType, kMetadataBufferTypeGrallocSource);
1012d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar
1013d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
1014ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                (unsigned)(oldest - &mBuffers[kPortIndexOutput][0]),
1015054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mDequeueCounter - oldest->mDequeuedAt,
1016d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                metaData->pHandle,
1017d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                oldest->mGraphicBuffer->handle, oldest->mData->base());
1018054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1019054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return oldest;
1020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
1023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
1025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1027f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
1028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[portIndex].size(); i-- > 0;) {
1029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, freeBuffer(portIndex, i));
1030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDealer[portIndex].clear();
1033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1037349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huberstatus_t ACodec::freeOutputBuffersNotOwnedByComponent() {
1038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
1039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
1040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
1041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10422ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // At this time some buffers may still be with the component
10432ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // or being drained.
10442ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT &&
10452ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar            info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) {
1046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK, freeBuffer(kPortIndexOutput, i));
1047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1053f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
1054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
1055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(info->mStatus == BufferInfo::OWNED_BY_US
1057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
1058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput && mNativeWindow != NULL
1060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && info->mStatus == BufferInfo::OWNED_BY_US) {
10613fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        cancelBufferToNativeWindow(info);
1062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(mOMX->freeBuffer(
1065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, portIndex, info->mBufferID),
1066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
1067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mBuffers[portIndex].removeAt(i);
1069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1073f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::findBufferByID(
1074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        uint32_t portIndex, IOMX::buffer_id bufferID,
1075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ssize_t *index) {
1076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
1077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
1078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mBufferID == bufferID) {
1080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (index != NULL) {
1081f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                *index = i;
1082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
1084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1086f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
1088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1089f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
1090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10925778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setComponentRole(
1093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        bool isEncoder, const char *mime) {
1094f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    struct MimeToRole {
1095f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime;
1096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *decoderRole;
1097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *encoderRole;
1098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
1099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const MimeToRole kMimeToRole[] = {
1101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG,
1102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.mp3", "audio_encoder.mp3" },
11032944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
11042944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp1", "audio_encoder.mp1" },
11052944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
11062944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp2", "audio_encoder.mp2" },
1107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_NB,
1108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrnb", "audio_encoder.amrnb" },
1109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_WB,
1110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrwb", "audio_encoder.amrwb" },
1111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AAC,
1112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.aac", "audio_encoder.aac" },
1113729de186450f78c099637e1fce743fe531862c52Andreas Huber        { MEDIA_MIMETYPE_AUDIO_VORBIS,
1114729de186450f78c099637e1fce743fe531862c52Andreas Huber            "audio_decoder.vorbis", "audio_encoder.vorbis" },
1115bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian        { MEDIA_MIMETYPE_AUDIO_OPUS,
1116bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian            "audio_decoder.opus", "audio_encoder.opus" },
1117c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_MLAW,
1118c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" },
1119c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_ALAW,
1120c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711alaw", "audio_encoder.g711alaw" },
1121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_AVC,
1122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.avc", "video_encoder.avc" },
11232472b1c0d63454e5d90a982bd6c555de6c3127bdRachad        { MEDIA_MIMETYPE_VIDEO_HEVC,
11242472b1c0d63454e5d90a982bd6c555de6c3127bdRachad            "video_decoder.hevc", "video_encoder.hevc" },
1125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_MPEG4,
1126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.mpeg4", "video_encoder.mpeg4" },
1127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_H263,
1128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.h263", "video_encoder.h263" },
112994705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP8,
113094705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp8", "video_encoder.vp8" },
113194705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP9,
113294705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp9", "video_encoder.vp9" },
1133ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        { MEDIA_MIMETYPE_AUDIO_RAW,
1134ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            "audio_decoder.raw", "audio_encoder.raw" },
11352f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        { MEDIA_MIMETYPE_AUDIO_FLAC,
11362f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            "audio_decoder.flac", "audio_encoder.flac" },
1137ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        { MEDIA_MIMETYPE_AUDIO_MSGSM,
1138ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen            "audio_decoder.gsm", "audio_encoder.gsm" },
1139774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu        { MEDIA_MIMETYPE_VIDEO_MPEG2,
1140774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu            "video_decoder.mpeg2", "video_encoder.mpeg2" },
114197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        { MEDIA_MIMETYPE_AUDIO_AC3,
114297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            "audio_decoder.ac3", "audio_encoder.ac3" },
11438a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        { MEDIA_MIMETYPE_AUDIO_EAC3,
11448a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            "audio_decoder.eac3", "audio_encoder.eac3" },
1145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
1146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const size_t kNumMimeToRole =
1148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
1149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    size_t i;
1151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (i = 0; i < kNumMimeToRole; ++i) {
1152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcasecmp(mime, kMimeToRole[i].mime)) {
1153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (i == kNumMimeToRole) {
11585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_UNSUPPORTED;
1159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    const char *role =
1162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        isEncoder ? kMimeToRole[i].encoderRole
1163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                  : kMimeToRole[i].decoderRole;
1164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (role != NULL) {
1166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_PARAM_COMPONENTROLETYPE roleParams;
1167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        InitOMXParams(&roleParams);
1168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        strncpy((char *)roleParams.cRole,
1170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                role, OMX_MAX_STRINGNAME_SIZE - 1);
1171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
1173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->setParameter(
1175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamStandardComponentRole,
1176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &roleParams, sizeof(roleParams));
1177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
11795ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("[%s] Failed to set standard component role '%s'.",
1180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 mComponentName.c_str(), role);
11815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
1183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
11855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
1187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
11895778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::configureCodec(
1190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime, const sp<AMessage> &msg) {
11915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t encoder;
11925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("encoder", &encoder)) {
11935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        encoder = false;
11945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1196e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    sp<AMessage> inputFormat = new AMessage();
11974e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    sp<AMessage> outputFormat = mNotify->dup(); // will use this for kWhatOutputFormatChanged
1198e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
11995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mIsEncoder = encoder;
1200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
12018db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu
12025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setComponentRole(encoder /* isEncoder */, mime);
12035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
12055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
12065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
12075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitRate = 0;
12092f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    // FLAC encoder doesn't need a bitrate, other encoders do
12102f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
12112f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            && !msg->findInt32("bitrate", &bitRate)) {
12125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
12135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
12145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1215d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    int32_t storeMeta;
1216d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (encoder
1217d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && msg->findInt32("store-metadata-in-buffers", &storeMeta)
1218d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && storeMeta != 0) {
1219d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE);
1220d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1221d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (err != OK) {
1222308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              ALOGE("[%s] storeMetaDataInBuffers (input) failed w/ err %d",
1223308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    mComponentName.c_str(), err);
1224d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1225308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              return err;
1226308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang          }
1227308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang      }
1228d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1229308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t prependSPSPPS = 0;
12303a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    if (encoder
12313a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
12323a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && prependSPSPPS != 0) {
12333a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        OMX_INDEXTYPE index;
12343a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        err = mOMX->getExtensionIndex(
12353a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                mNode,
12363a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                "OMX.google.android.index.prependSPSPPSToIDRFrames",
12373a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                &index);
12383a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
12393a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err == OK) {
12403a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            PrependSPSPPSToIDRFramesParams params;
12413a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            InitOMXParams(&params);
12423a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            params.bEnable = OMX_TRUE;
12433a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
12443a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            err = mOMX->setParameter(
12453a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                    mNode, index, &params, sizeof(params));
12463a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
12473a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
12483a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err != OK) {
12493a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            ALOGE("Encoder could not be configured to emit SPS/PPS before "
12503a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                  "IDR frames. (err %d)", err);
12513a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
12523a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            return err;
12533a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
12543a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    }
12553a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
1256308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // Only enable metadata mode on encoder output if encoder can prepend
1257308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // sps/pps to idr frames, since in metadata mode the bitstream is in an
1258308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // opaque handle, to which we don't have access.
1259308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t video = !strncasecmp(mime, "video/", 6);
12608db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    mIsVideo = video;
1261308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (encoder && video) {
1262308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS
1263308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && msg->findInt32("store-metadata-in-buffers-output", &storeMeta)
1264308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && storeMeta != 0);
1265308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1266308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, enable);
1267308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1268308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        if (err != OK) {
1269308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            ALOGE("[%s] storeMetaDataInBuffers (output) failed w/ err %d",
1270308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                mComponentName.c_str(), err);
1271308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = 0;
1272308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        } else {
1273308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = enable;
1274308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        }
1275a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
1276a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (!msg->findInt64(
1277a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    "repeat-previous-frame-after",
1278a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    &mRepeatFrameDelayUs)) {
1279a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            mRepeatFrameDelayUs = -1ll;
1280a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
128194ee4b708acfa941581160b267afb79192b1d816Chong Zhang
128294ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (!msg->findInt64("max-pts-gap-to-encoder", &mMaxPtsGapUs)) {
12832c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mMaxPtsGapUs = -1ll;
12842c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
12852c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
128637b2b389139ed638831e49708c947863eef631efRonghua Wu        if (!msg->findFloat("max-fps-to-encoder", &mMaxFps)) {
128737b2b389139ed638831e49708c947863eef631efRonghua Wu            mMaxFps = -1;
128837b2b389139ed638831e49708c947863eef631efRonghua Wu        }
128937b2b389139ed638831e49708c947863eef631efRonghua Wu
12902c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (!msg->findInt64("time-lapse", &mTimePerCaptureUs)) {
12912c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mTimePerCaptureUs = -1ll;
129294ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
129372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
129472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (!msg->findInt32(
129572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    "create-input-buffers-suspended",
129672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    (int32_t*)&mCreateInputBuffersSuspended)) {
129772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mCreateInputBuffersSuspended = false;
129872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
1299308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    }
1300308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
13013a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar    // NOTE: we only use native window for video decoders
1302054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    sp<RefBase> obj;
13030d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    bool haveNativeWindow = msg->findObject("native-window", &obj)
13043a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            && obj != NULL && video && !encoder;
1305054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mStoreMetaDataInOutputBuffers = false;
1306e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if (video && !encoder) {
1307e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        inputFormat->setInt32("adaptive-playback", false);
13081713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang
13091713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        int32_t usageProtected;
13101713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        if (msg->findInt32("protected", &usageProtected) && usageProtected) {
13111713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            if (!haveNativeWindow) {
13121713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang                ALOGE("protected output buffers must be sent to an ANativeWindow");
13131713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang                return PERMISSION_DENIED;
13141713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            }
13151713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            mFlags |= kFlagIsGrallocUsageProtected;
13161713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
13171713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        }
1318e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
13193a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar    if (haveNativeWindow) {
13201de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar        sp<ANativeWindow> nativeWindow =
13211de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar            static_cast<ANativeWindow *>(static_cast<Surface *>(obj.get()));
13225a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
13236597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        // START of temporary support for automatic FRC - THIS WILL BE REMOVED
13246597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        int32_t autoFrc;
13256597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        if (msg->findInt32("auto-frc", &autoFrc)) {
13266597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            bool enabled = autoFrc;
13276597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            OMX_CONFIG_BOOLEANTYPE config;
13286597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            InitOMXParams(&config);
13296597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            config.bEnabled = (OMX_BOOL)enabled;
13306597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            status_t temp = mOMX->setConfig(
13316597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                    mNode, (OMX_INDEXTYPE)OMX_IndexConfigAutoFramerateConversion,
13326597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                    &config, sizeof(config));
13336597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            if (temp == OK) {
13346597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                outputFormat->setInt32("auto-frc", enabled);
13356597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            } else if (enabled) {
13366597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                ALOGI("codec does not support requested auto-frc (err %d)", temp);
13376597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            }
13386597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        }
13396597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        // END of temporary support for automatic FRC
13406597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar
13415a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        int32_t tunneled;
13425a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        if (msg->findInt32("feature-tunneled-playback", &tunneled) &&
13435a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            tunneled != 0) {
13445a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            ALOGI("Configuring TUNNELED video playback.");
1345ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            mTunneled = true;
13465a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
134797827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad            int32_t audioHwSync = 0;
134897827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad            if (!msg->findInt32("audio-hw-sync", &audioHwSync)) {
13495a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGW("No Audio HW Sync provided for video tunnel");
13505a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            }
13515a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            err = configureTunneledVideoPlayback(audioHwSync, nativeWindow);
13525a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (err != OK) {
135397827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad                ALOGE("configureTunneledVideoPlayback(%d,%p) failed!",
13545a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        audioHwSync, nativeWindow.get());
13555a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                return err;
1356fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
1357fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1358d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            int32_t maxWidth = 0, maxHeight = 0;
1359d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            if (msg->findInt32("max-width", &maxWidth) &&
1360d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    msg->findInt32("max-height", &maxHeight)) {
1361d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad
1362d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                err = mOMX->prepareForAdaptivePlayback(
1363d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                        mNode, kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight);
1364d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                if (err != OK) {
1365d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    ALOGW("[%s] prepareForAdaptivePlayback failed w/ err %d",
1366d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                            mComponentName.c_str(), err);
13673a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    // allow failure
13683a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    err = OK;
1369d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                } else {
1370d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("max-width", maxWidth);
1371d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("max-height", maxHeight);
1372d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("adaptive-playback", true);
1373d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                }
1374d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            }
13755a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        } else {
1376ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            ALOGV("Configuring CPU controlled video playback.");
1377ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            mTunneled = false;
1378ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
13793fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // Explicity reset the sideband handle of the window for
13803fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // non-tunneled video in case the window was previously used
13813fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // for a tunneled video playback.
13823fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            err = native_window_set_sideband_stream(nativeWindow.get(), NULL);
13833fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            if (err != OK) {
13843fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad                ALOGE("set_sideband_stream(NULL) failed! (err %d).", err);
13853fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad                return err;
13863fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            }
13873fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad
13885a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            // Always try to enable dynamic output buffers on native surface
13895a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            err = mOMX->storeMetaDataInBuffers(
13905a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    mNode, kPortIndexOutput, OMX_TRUE);
13915a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (err != OK) {
13925a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d",
1393fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        mComponentName.c_str(), err);
1394e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
13955a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // if adaptive playback has been requested, try JB fallback
13965a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // NOTE: THIS FALLBACK MECHANISM WILL BE REMOVED DUE TO ITS
13975a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // LARGE MEMORY REQUIREMENT
13985a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
13995a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // we will not do adaptive playback on software accessed
14005a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // surfaces as they never had to respond to changes in the
14015a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // crop window, and we don't trust that they will be able to.
14025a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                int usageBits = 0;
14035a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                bool canDoAdaptivePlayback;
14045a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
14055a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                if (nativeWindow->query(
14065a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        nativeWindow.get(),
14075a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        NATIVE_WINDOW_CONSUMER_USAGE_BITS,
14085a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        &usageBits) != OK) {
14095a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    canDoAdaptivePlayback = false;
14105a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                } else {
14115a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    canDoAdaptivePlayback =
14125a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        (usageBits &
14135a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                                (GRALLOC_USAGE_SW_READ_MASK |
14145a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                                 GRALLOC_USAGE_SW_WRITE_MASK)) == 0;
14155a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                }
14165a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
14175a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                int32_t maxWidth = 0, maxHeight = 0;
14185a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                if (canDoAdaptivePlayback &&
14195a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        msg->findInt32("max-width", &maxWidth) &&
14205a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        msg->findInt32("max-height", &maxHeight)) {
14215a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    ALOGV("[%s] prepareForAdaptivePlayback(%dx%d)",
14225a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mComponentName.c_str(), maxWidth, maxHeight);
14235a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
14245a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    err = mOMX->prepareForAdaptivePlayback(
14255a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mNode, kPortIndexOutput, OMX_TRUE, maxWidth,
14265a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            maxHeight);
14275a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    ALOGW_IF(err != OK,
14285a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            "[%s] prepareForAdaptivePlayback failed w/ err %d",
14295a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mComponentName.c_str(), err);
14305a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
14315a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    if (err == OK) {
14325a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("max-width", maxWidth);
14335a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("max-height", maxHeight);
14345a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("adaptive-playback", true);
14355a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    }
1436e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
14375a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // allow failure
14385a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                err = OK;
14395a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            } else {
14405a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGV("[%s] storeMetaDataInBuffers succeeded",
14415a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        mComponentName.c_str());
14425a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                mStoreMetaDataInOutputBuffers = true;
14435a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                inputFormat->setInt32("adaptive-playback", true);
1444fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
14450167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber
14465a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            int32_t push;
14475a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (msg->findInt32("push-blank-buffers-on-shutdown", &push)
14485a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    && push != 0) {
14495a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
14505a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            }
14510167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        }
1452e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang
1453e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        int32_t rotationDegrees;
1454e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        if (msg->findInt32("rotation-degrees", &rotationDegrees)) {
1455e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            mRotationDegrees = rotationDegrees;
1456e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        } else {
1457e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            mRotationDegrees = 0;
1458e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        }
1459054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1460054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1461308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (video) {
14623a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // determine need for software renderer
14633a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        bool usingSwRenderer = false;
14643a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (haveNativeWindow && mComponentName.startsWith("OMX.google.")) {
14653a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            usingSwRenderer = true;
14663a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            haveNativeWindow = false;
14673a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
14683a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
14695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (encoder) {
14705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupVideoEncoder(mime, msg);
14715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
14720d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            err = setupVideoDecoder(mime, msg, haveNativeWindow);
14735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14743a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
14753a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (err != OK) {
14763a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            return err;
14773a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
14783a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
14793a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (haveNativeWindow) {
14801de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar            mNativeWindow = static_cast<Surface *>(obj.get());
14811de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar            CHECK(mNativeWindow != NULL);
14823a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
14833a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            native_window_set_scaling_mode(
14843a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    mNativeWindow.get(), NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
14853a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
14863a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
14873a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // initialize native window now to get actual output format
14883a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // TODO: this is needed for some encoders even though they don't use native window
14893a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        CHECK_EQ((status_t)OK, initNativeWindow());
14903a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
14913a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // fallback for devices that do not handle flex-YUV for native buffers
14923a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (haveNativeWindow) {
14933a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            int32_t requestedColorFormat = OMX_COLOR_FormatUnused;
14943a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            if (msg->findInt32("color-format", &requestedColorFormat) &&
14953a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    requestedColorFormat == OMX_COLOR_FormatYUV420Flexible) {
14963a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                CHECK_EQ(getPortFormat(kPortIndexOutput, outputFormat), (status_t)OK);
14973a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                int32_t colorFormat = OMX_COLOR_FormatUnused;
14983a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                OMX_U32 flexibleEquivalent = OMX_COLOR_FormatUnused;
14993a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                CHECK(outputFormat->findInt32("color-format", &colorFormat));
15003a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                ALOGD("[%s] Requested output format %#x and got %#x.",
15013a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        mComponentName.c_str(), requestedColorFormat, colorFormat);
15023a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                if (!isFlexibleColorFormat(
15033a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                                mOMX, mNode, colorFormat, haveNativeWindow, &flexibleEquivalent)
15043a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        || flexibleEquivalent != (OMX_U32)requestedColorFormat) {
15053a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    // device did not handle flex-YUV request for native window, fall back
15063a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    // to SW renderer
15073a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    ALOGI("[%s] Falling back to software renderer", mComponentName.c_str());
15083a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    mNativeWindow.clear();
15093a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    haveNativeWindow = false;
15103a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    usingSwRenderer = true;
15113a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    if (mStoreMetaDataInOutputBuffers) {
15123a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, OMX_FALSE);
15133a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        mStoreMetaDataInOutputBuffers = false;
15143a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        // TODO: implement adaptive-playback support for bytebuffer mode.
15153a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        // This is done by SW codecs, but most HW codecs don't support it.
15163a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        inputFormat->setInt32("adaptive-playback", false);
15173a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
15183a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    if (err == OK) {
15193a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        err = mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
15203a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
15213a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    if (mFlags & kFlagIsGrallocUsageProtected) {
15223a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        // fallback is not supported for protected playback
15233a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        err = PERMISSION_DENIED;
15243a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    } else if (err == OK) {
15253a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        err = setupVideoDecoder(mime, msg, false);
15263a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
15273a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                }
15283a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            }
15293a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
15303a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
15313a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (usingSwRenderer) {
15323a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            outputFormat->setInt32("using-sw-renderer", 1);
15333a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
153442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
153542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        int32_t numChannels, sampleRate;
153642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        if (!msg->findInt32("channel-count", &numChannels)
153742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
153842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // Since we did not always check for these, leave them optional
153942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // and have the decoder figure it all out.
154042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = OK;
154142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        } else {
154242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = setupRawAudioFormat(
154342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    encoder ? kPortIndexInput : kPortIndexOutput,
154442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    sampleRate,
154542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    numChannels);
154642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        }
1547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
1548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t numChannels, sampleRate;
15495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)
15505778822d86b0337407514b9372562b86edfa91cdAndreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
15515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
15525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
1553aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            int32_t isADTS, aacProfile;
1554b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            int32_t sbrMode;
15558045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            int32_t maxOutputChannelCount;
15562965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            int32_t pcmLimiterEnable;
15578045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            drcParams_t drc;
1558ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            if (!msg->findInt32("is-adts", &isADTS)) {
1559ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                isADTS = 0;
1560ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
1561aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (!msg->findInt32("aac-profile", &aacProfile)) {
1562aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                aacProfile = OMX_AUDIO_AACObjectNull;
1563aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
1564b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            if (!msg->findInt32("aac-sbr-mode", &sbrMode)) {
1565b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                sbrMode = -1;
1566b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            }
1567ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
15688045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-max-output-channel_count", &maxOutputChannelCount)) {
15698045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                maxOutputChannelCount = -1;
15708045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
15712965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            if (!msg->findInt32("aac-pcm-limiter-enable", &pcmLimiterEnable)) {
15722965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                // value is unknown
15732965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                pcmLimiterEnable = -1;
15742965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            }
15758045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-encoded-target-level", &drc.encodedTargetLevel)) {
15768045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
15778045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.encodedTargetLevel = -1;
15788045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
15798045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-cut-level", &drc.drcCut)) {
15808045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
15818045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.drcCut = -1;
15828045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
15838045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-boost-level", &drc.drcBoost)) {
15848045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
15858045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.drcBoost = -1;
15868045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
15878045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-heavy-compression", &drc.heavyCompression)) {
15888045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
15898045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.heavyCompression = -1;
15908045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
15918045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-target-ref-level", &drc.targetRefLevel)) {
15928045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
15938045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.targetRefLevel = -1;
15948045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
15958045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi
1596ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            err = setupAACCodec(
15974471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    encoder, numChannels, sampleRate, bitRate, aacProfile,
15982965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                    isADTS != 0, sbrMode, maxOutputChannelCount, drc,
15992965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                    pcmLimiterEnable);
16005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
1601729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
16025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
1603729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
16045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
1605729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
1606729de186450f78c099637e1fce743fe531862c52Andreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
1607729de186450f78c099637e1fce743fe531862c52Andreas Huber        // These are PCM-like formats with a fixed sample rate but
1608729de186450f78c099637e1fce743fe531862c52Andreas Huber        // a variable number of channels.
1609729de186450f78c099637e1fce743fe531862c52Andreas Huber
1610729de186450f78c099637e1fce743fe531862c52Andreas Huber        int32_t numChannels;
16115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)) {
16125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
16135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
161417c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            int32_t sampleRate;
161517c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            if (!msg->findInt32("sample-rate", &sampleRate)) {
161617c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen                sampleRate = 8000;
161717c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            }
161817c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            err = setupG711Codec(encoder, sampleRate, numChannels);
16195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16202f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
1621ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        int32_t numChannels = 0, sampleRate = 0, compressionLevel = -1;
16222f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (encoder &&
16232f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                (!msg->findInt32("channel-count", &numChannels)
16242f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                        || !msg->findInt32("sample-rate", &sampleRate))) {
16252f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("missing channel count or sample rate for FLAC encoder");
16262f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            err = INVALID_OPERATION;
16272f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        } else {
16282f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            if (encoder) {
1629516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                if (!msg->findInt32(
1630cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                            "complexity", &compressionLevel) &&
1631cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                    !msg->findInt32(
1632516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                            "flac-compression-level", &compressionLevel)) {
1633cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                    compressionLevel = 5; // default FLAC compression level
16342f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel < 0) {
1635516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1636516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 0",
1637516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
16382f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 0;
16392f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel > 8) {
1640516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1641516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 8",
1642516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
16432f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 8;
16442f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                }
16452f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            }
1646516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            err = setupFlacCodec(
1647516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    encoder, numChannels, sampleRate, compressionLevel);
16482f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
1649ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
1650ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        int32_t numChannels, sampleRate;
1651ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        if (encoder
1652ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("channel-count", &numChannels)
1653ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
1654ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = INVALID_OPERATION;
1655ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        } else {
1656ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
1657ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        }
165897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AC3)) {
165997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t numChannels;
166097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t sampleRate;
166197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        if (!msg->findInt32("channel-count", &numChannels)
166297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                || !msg->findInt32("sample-rate", &sampleRate)) {
166397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = INVALID_OPERATION;
166497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        } else {
166597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = setupAC3Codec(encoder, numChannels, sampleRate);
166697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        }
16678a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_EAC3)) {
16688a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        int32_t numChannels;
16698a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        int32_t sampleRate;
16708a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        if (!msg->findInt32("channel-count", &numChannels)
16718a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                || !msg->findInt32("sample-rate", &sampleRate)) {
16728a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            err = INVALID_OPERATION;
16738a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        } else {
16748a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            err = setupEAC3Codec(encoder, numChannels, sampleRate);
16758a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        }
16765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1677729de186450f78c099637e1fce743fe531862c52Andreas Huber
16784471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    if (err != OK) {
16794471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber        return err;
16804471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    }
16814471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber
16828b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
16838b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderDelay = 0;
16848b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
16859806555d3930be43e11106281dee354820ac1c88Andreas Huber
16868b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
16878b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderPadding = 0;
16888b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
16898b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen
16909806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (msg->findInt32("channel-mask", &mChannelMask)) {
16919806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = true;
16929806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else {
16939806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = false;
16949806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
16959806555d3930be43e11106281dee354820ac1c88Andreas Huber
1696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t maxInputSize;
1697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (msg->findInt32("max-input-size", &maxInputSize)) {
16985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
1699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
17005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
1701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
17025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17038b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    int32_t priority;
17048b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    if (msg->findInt32("priority", &priority)) {
17058b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu        err = setPriority(priority);
17068b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    }
17078b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu
1708ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    int32_t rateInt = -1;
1709ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    float rateFloat = -1;
1710ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (!msg->findFloat("operating-rate", &rateFloat)) {
1711ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        msg->findInt32("operating-rate", &rateInt);
1712ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        rateFloat = (float)rateInt;  // 16MHz (FLINTMAX) is OK for upper bound.
1713ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
1714ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (rateFloat > 0) {
1715ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        err = setOperatingRate(rateFloat, video);
1716ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
1717ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu
17184e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    mBaseOutputFormat = outputFormat;
17194e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar
1720e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ(getPortFormat(kPortIndexInput, inputFormat), (status_t)OK);
1721e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ(getPortFormat(kPortIndexOutput, outputFormat), (status_t)OK);
1722e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mInputFormat = inputFormat;
1723e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mOutputFormat = outputFormat;
1724e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
17255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
1726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
17288b806ea894ca098366629458bfdd1df4866afcdfRonghua Wustatus_t ACodec::setPriority(int32_t priority) {
17298b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    if (priority < 0) {
17308b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu        return BAD_VALUE;
17318b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    }
17328b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    OMX_PARAM_U32TYPE config;
17338b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    InitOMXParams(&config);
17348b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    config.nU32 = (OMX_U32)priority;
17358b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    status_t temp = mOMX->setConfig(
17368b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu            mNode, (OMX_INDEXTYPE)OMX_IndexConfigPriority,
17378b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu            &config, sizeof(config));
17388b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    if (temp != OK) {
17398b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu        ALOGI("codec does not support config priority (err %d)", temp);
17408b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    }
17418b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    return OK;
17428b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu}
17438b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu
1744ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wustatus_t ACodec::setOperatingRate(float rateFloat, bool isVideo) {
1745ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (rateFloat < 0) {
1746ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        return BAD_VALUE;
1747ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
1748ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    OMX_U32 rate;
1749ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (isVideo) {
1750ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        if (rateFloat > 65535) {
1751ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            return BAD_VALUE;
1752ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        }
1753ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        rate = (OMX_U32)(rateFloat * 65536.0f + 0.5f);
1754ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    } else {
1755ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        if (rateFloat > UINT_MAX) {
1756ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            return BAD_VALUE;
1757ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        }
1758ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        rate = (OMX_U32)(rateFloat);
1759ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
1760ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    OMX_PARAM_U32TYPE config;
1761ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    InitOMXParams(&config);
1762ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    config.nU32 = rate;
1763ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    status_t err = mOMX->setConfig(
1764ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            mNode, (OMX_INDEXTYPE)OMX_IndexConfigOperatingRate,
1765ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            &config, sizeof(config));
1766ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (err != OK) {
1767ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        ALOGI("codec does not support config operating rate (err %d)", err);
1768ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
1769ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    return OK;
1770ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu}
1771ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu
1772f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
1773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
1775f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
1776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (def.nBufferSize >= size) {
1785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
1786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nBufferSize = size;
1789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
1791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->getParameter(
1798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(def.nBufferSize >= size);
1805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
18095778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::selectAudioPortFormat(
18105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
18115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_AUDIO_PARAM_PORTFORMATTYPE format;
18125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&format);
18135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    format.nPortIndex = portIndex;
18155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (OMX_U32 index = 0;; ++index) {
18165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        format.nIndex = index;
18175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
18195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioPortFormat,
18205778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &format, sizeof(format));
18215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
18235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
18245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (format.eEncoding == desiredFormat) {
18275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
18285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
18325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format));
18335778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
18345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18355778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAACCodec(
1836aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        bool encoder, int32_t numChannels, int32_t sampleRate,
18378045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        int32_t bitRate, int32_t aacProfile, bool isADTS, int32_t sbrMode,
18382965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang        int32_t maxOutputChannelCount, const drcParams_t& drc,
18392965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang        int32_t pcmLimiterEnable) {
1840ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (encoder && isADTS) {
1841ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return -EINVAL;
1842ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
1843ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
18445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setupRawAudioFormat(
18455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
18465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sampleRate,
18475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            numChannels);
18485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (encoder) {
18545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
18555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
18575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
18585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
18615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
18625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = kPortIndexOutput;
18635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
18655778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
18665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
18685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
18695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.bFlagErrorConcealment = OMX_TRUE;
18725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
18735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
18755778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
18765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
18785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
18795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
18825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&profile);
18835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nPortIndex = kPortIndexOutput;
18845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
18865778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
18875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
18895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
18905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nChannels = numChannels;
18935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eChannelMode =
18955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (numChannels == 1)
18965778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
18975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nSampleRate = sampleRate;
18995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nBitRate = bitRate;
19005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAudioBandWidth = 0;
19015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nFrameLength = 0;
19025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACtools = OMX_AUDIO_AACToolAll;
19035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACERtools = OMX_AUDIO_AACERNone;
1904aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
19055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
1906b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        switch (sbrMode) {
1907b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 0:
1908b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // disable sbr
1909b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
1910b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
1911b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
1912b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 1:
1913b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable single-rate sbr
1914b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
1915b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
1916b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
1917b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 2:
1918b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable dual-rate sbr
1919b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
1920b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
1921b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
1922b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case -1:
1923b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable both modes -> the codec will decide which mode should be used
1924b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
1925b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
1926b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
1927b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        default:
1928b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // unsupported sbr mode
1929b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            return BAD_VALUE;
1930b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        }
1931b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi
19325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
19345778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
19355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
19375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
19385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_AUDIO_PARAM_AACPROFILETYPE profile;
1944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&profile);
1945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nPortIndex = kPortIndexInput;
1946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
19475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
1948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
1949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nChannels = numChannels;
1955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nSampleRate = sampleRate;
1956ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1957ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    profile.eAACStreamFormat =
1958ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        isADTS
1959ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            ? OMX_AUDIO_AACStreamFormatMP4ADTS
1960ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            : OMX_AUDIO_AACStreamFormatMP4FF;
1961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
19628045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    OMX_AUDIO_PARAM_ANDROID_AACPRESENTATIONTYPE presentation;
19638045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nMaxOutputChannels = maxOutputChannelCount;
19648045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nDrcCut = drc.drcCut;
19658045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nDrcBoost = drc.drcBoost;
19668045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nHeavyCompression = drc.heavyCompression;
19678045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nTargetReferenceLevel = drc.targetRefLevel;
19688045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nEncodedTargetLevel = drc.encodedTargetLevel;
19692965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang    presentation.nPCMLimiterEnable = pcmLimiterEnable;
19708045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi
19718045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    status_t res = mOMX->setParameter(mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
19728045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    if (res == OK) {
19738045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        // optional parameters, will not cause configuration failure
19748045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        mOMX->setParameter(mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAacPresentation,
19758045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                &presentation, sizeof(presentation));
19768045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    } else {
19778045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        ALOGW("did not set AudioAndroidAacPresentation due to error %d when setting AudioAac", res);
19788045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    }
19798045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    return res;
19805778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
198297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryustatus_t ACodec::setupAC3Codec(
198397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        bool encoder, int32_t numChannels, int32_t sampleRate) {
198497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    status_t err = setupRawAudioFormat(
198597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
198697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
198797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
198897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
198997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
199097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
199197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (encoder) {
199297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        ALOGW("AC3 encoding is not supported.");
199397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return INVALID_OPERATION;
199497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
199597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
199697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    OMX_AUDIO_PARAM_ANDROID_AC3TYPE def;
199797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    InitOMXParams(&def);
199897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nPortIndex = kPortIndexInput;
199997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
200097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    err = mOMX->getParameter(
200197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
200297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
200397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
200497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
200597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
200697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
200797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
200897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
200997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
201097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nChannels = numChannels;
201197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nSampleRate = sampleRate;
201297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
201397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    return mOMX->setParameter(
201497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
201597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
201697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
201797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
201897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu}
201997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
20208a4728966dc9c78e21c3c93a927707e93c05e5e0Rachadstatus_t ACodec::setupEAC3Codec(
20218a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        bool encoder, int32_t numChannels, int32_t sampleRate) {
20228a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    status_t err = setupRawAudioFormat(
20238a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
20248a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
20258a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (err != OK) {
20268a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return err;
20278a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
20288a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
20298a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (encoder) {
20308a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        ALOGW("EAC3 encoding is not supported.");
20318a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return INVALID_OPERATION;
20328a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
20338a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
20348a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    OMX_AUDIO_PARAM_ANDROID_EAC3TYPE def;
20358a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    InitOMXParams(&def);
20368a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nPortIndex = kPortIndexInput;
20378a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
20388a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    err = mOMX->getParameter(
20398a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            mNode,
20408a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
20418a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            &def,
20428a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            sizeof(def));
20438a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
20448a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (err != OK) {
20458a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return err;
20468a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
20478a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
20488a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nChannels = numChannels;
20498a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nSampleRate = sampleRate;
20508a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
20518a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    return mOMX->setParameter(
20528a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            mNode,
20538a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
20548a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            &def,
20558a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            sizeof(def));
20568a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad}
20578a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
20585778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
20595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        bool isAMRWB, int32_t bps) {
20605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (isAMRWB) {
20615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 6600) {
20625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB0;
20635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 8850) {
20645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB1;
20655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 12650) {
20665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB2;
20675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 14250) {
20685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB3;
20695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 15850) {
20705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB4;
20715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 18250) {
20725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB5;
20735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 19850) {
20745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB6;
20755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 23050) {
20765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB7;
20775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 23850 bps
20805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeWB8;
20815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {  // AMRNB
20825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 4750) {
20835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB0;
20845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5150) {
20855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB1;
20865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5900) {
20875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB2;
20885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 6700) {
20895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB3;
20905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7400) {
20915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB4;
20925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7950) {
20935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB5;
20945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 10200) {
20955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB6;
20965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 12200 bps
20995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeNB7;
21005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
21035778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
2104729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_AMRTYPE def;
2105729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
21065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
2107729de186450f78c099637e1fce743fe531862c52Andreas Huber
2108729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err =
2109729de186450f78c099637e1fce743fe531862c52Andreas Huber        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
2110729de186450f78c099637e1fce743fe531862c52Andreas Huber
2111729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2112729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2113729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2114729de186450f78c099637e1fce743fe531862c52Andreas Huber
2115729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
21165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
21175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
21195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
2120729de186450f78c099637e1fce743fe531862c52Andreas Huber
21215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2124729de186450f78c099637e1fce743fe531862c52Andreas Huber
21255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupRawAudioFormat(
21265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
21275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            isWAMR ? 16000 : 8000 /* sampleRate */,
21285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            1 /* numChannels */);
2129729de186450f78c099637e1fce743fe531862c52Andreas Huber}
2130729de186450f78c099637e1fce743fe531862c52Andreas Huber
213117c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissenstatus_t ACodec::setupG711Codec(bool encoder, int32_t sampleRate, int32_t numChannels) {
21325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(!encoder);  // XXX TODO
21335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2134729de186450f78c099637e1fce743fe531862c52Andreas Huber    return setupRawAudioFormat(
213517c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            kPortIndexInput, sampleRate, numChannels);
2136729de186450f78c099637e1fce743fe531862c52Andreas Huber}
2137729de186450f78c099637e1fce743fe531862c52Andreas Huber
21382f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivistatus_t ACodec::setupFlacCodec(
21392f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
21402f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
21412f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder) {
21422f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        OMX_AUDIO_PARAM_FLACTYPE def;
21432f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        InitOMXParams(&def);
21442f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nPortIndex = kPortIndexOutput;
21452f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
21462f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        // configure compression level
21472f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        status_t err = mOMX->getParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
21482f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
21492f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
21502f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
21512f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
21522f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nCompressionLevel = compressionLevel;
21532f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        err = mOMX->setParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
21542f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
21552f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
21562f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
21572f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
21582f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
21592f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
21602f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    return setupRawAudioFormat(
21612f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            encoder ? kPortIndexInput : kPortIndexOutput,
21622f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            sampleRate,
21632f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            numChannels);
21642f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi}
21652f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
2166729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t ACodec::setupRawAudioFormat(
2167729de186450f78c099637e1fce743fe531862c52Andreas Huber        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
2168729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
2169729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
2170729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.nPortIndex = portIndex;
2171729de186450f78c099637e1fce743fe531862c52Andreas Huber
2172729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err = mOMX->getParameter(
2173729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2174729de186450f78c099637e1fce743fe531862c52Andreas Huber
2175729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2176729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2177729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2178729de186450f78c099637e1fce743fe531862c52Andreas Huber
2179729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
2180729de186450f78c099637e1fce743fe531862c52Andreas Huber
2181729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->setParameter(
2182729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2183729de186450f78c099637e1fce743fe531862c52Andreas Huber
2184729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2185729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2186729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2187729de186450f78c099637e1fce743fe531862c52Andreas Huber
2188729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
2189729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&pcmParams);
2190729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nPortIndex = portIndex;
2191729de186450f78c099637e1fce743fe531862c52Andreas Huber
2192729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->getParameter(
2193729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
2194729de186450f78c099637e1fce743fe531862c52Andreas Huber
2195729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2196729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2197729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2198729de186450f78c099637e1fce743fe531862c52Andreas Huber
2199729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nChannels = numChannels;
2200729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.eNumData = OMX_NumericalDataSigned;
2201729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.bInterleaved = OMX_TRUE;
2202729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nBitPerSample = 16;
2203729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nSamplingRate = sampleRate;
2204729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
2205729de186450f78c099637e1fce743fe531862c52Andreas Huber
2206c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber    if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
2207c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber        return OMX_ErrorNone;
2208729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2209729de186450f78c099637e1fce743fe531862c52Andreas Huber
2210729de186450f78c099637e1fce743fe531862c52Andreas Huber    return mOMX->setParameter(
2211729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
2212729de186450f78c099637e1fce743fe531862c52Andreas Huber}
2213729de186450f78c099637e1fce743fe531862c52Andreas Huber
22145a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachadstatus_t ACodec::configureTunneledVideoPlayback(
221597827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad        int32_t audioHwSync, const sp<ANativeWindow> &nativeWindow) {
22165a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    native_handle_t* sidebandHandle;
22175a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
22185a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    status_t err = mOMX->configureVideoTunnelMode(
22195a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            mNode, kPortIndexOutput, OMX_TRUE, audioHwSync, &sidebandHandle);
22205a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    if (err != OK) {
22215a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        ALOGE("configureVideoTunnelMode failed! (err %d).", err);
22225a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        return err;
22235a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    }
22245a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
22255a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    err = native_window_set_sideband_stream(nativeWindow.get(), sidebandHandle);
22265a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    if (err != OK) {
22275a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        ALOGE("native_window_set_sideband_stream(%p) failed! (err %d).",
22285a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                sidebandHandle, err);
22295a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        return err;
22305a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    }
22315a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
22325a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    return OK;
22335a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad}
22345a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
2235f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoPortFormatType(
2236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
2237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_VIDEO_CODINGTYPE compressionFormat,
22380d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        OMX_COLOR_FORMATTYPE colorFormat,
22390d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        bool usingNativeBuffers) {
2240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
2241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
2242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = portIndex;
2243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
2244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool found = false;
2245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 index = 0;
2247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (;;) {
2248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        format.nIndex = index;
2249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->getParameter(
2250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamVideoPortFormat,
2251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &format, sizeof(format));
2252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
2254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return err;
2255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2257229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        // substitute back flexible color format to codec supported format
2258229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        OMX_U32 flexibleEquivalent;
22590d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (compressionFormat == OMX_VIDEO_CodingUnused
22600d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && isFlexibleColorFormat(
22610d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        mOMX, mNode, format.eColorFormat, usingNativeBuffers, &flexibleEquivalent)
22620d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && colorFormat == flexibleEquivalent) {
2263229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            ALOGI("[%s] using color format %#x in place of %#x",
2264229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                    mComponentName.c_str(), format.eColorFormat, colorFormat);
2265229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            colorFormat = format.eColorFormat;
2266229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
2267229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
2268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The following assertion is violated by TI's video decoder.
2269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // CHECK_EQ(format.nIndex, index);
2270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
2272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexInput
2273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && colorFormat == format.eColorFormat) {
2274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eCompressionFormat does not seem right.
2275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
2276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
2277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexOutput
2279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && compressionFormat == format.eCompressionFormat) {
2280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eColorFormat does not seem right.
2281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
2282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
2283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (format.eCompressionFormat == compressionFormat
2287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && format.eColorFormat == colorFormat) {
2288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            found = true;
2289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ++index;
2293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!found) {
2296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return UNKNOWN_ERROR;
2297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->setParameter(
2300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
2301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
2302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
2304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
23060d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// Set optimal output format. OMX component lists output formats in the order
23070d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// of preference, but this got more complicated since the introduction of flexible
23080d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// YUV formats. We support a legacy behavior for applications that do not use
23090d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// surface output, do not specify an output format, but expect a "usable" standard
23100d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// OMX format. SW readable and standard formats must be flex-YUV.
23110d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar//
23120d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// Suggested preference order:
23130d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal format for texture rendering (mediaplayer behavior)
23140d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal SW readable & texture renderable format (flex-YUV support)
23150d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal SW readable non-renderable format (flex-YUV bytebuffer support)
23160d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - legacy "usable" standard formats
23170d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar//
23180d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// For legacy support, we prefer a standard format, but will settle for a SW readable
23190d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// flex-YUV format.
23200d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnarstatus_t ACodec::setSupportedOutputFormat(bool getLegacyFlexibleFormat) {
23210d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    OMX_VIDEO_PARAM_PORTFORMATTYPE format, legacyFormat;
2322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
2323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = kPortIndexOutput;
2324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
23250d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    InitOMXParams(&legacyFormat);
23260d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    // this field will change when we find a suitable legacy format
23270d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    legacyFormat.eColorFormat = OMX_COLOR_FormatUnused;
2328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
23290d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    for (OMX_U32 index = 0; ; ++index) {
23300d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        format.nIndex = index;
23310d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        status_t err = mOMX->getParameter(
23320d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                mNode, OMX_IndexParamVideoPortFormat,
23330d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                &format, sizeof(format));
23340d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (err != OK) {
23350d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            // no more formats, pick legacy format if found
23360d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            if (legacyFormat.eColorFormat != OMX_COLOR_FormatUnused) {
23370d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                 memcpy(&format, &legacyFormat, sizeof(format));
23380d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                 break;
23390d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            }
23400d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            return err;
23410d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
23420d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (format.eCompressionFormat != OMX_VIDEO_CodingUnused) {
23430d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            return OMX_ErrorBadParameter;
23440d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
23450d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (!getLegacyFlexibleFormat) {
23460d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            break;
23470d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
23480d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        // standard formats that were exposed to users before
23490d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (format.eColorFormat == OMX_COLOR_FormatYUV420Planar
23500d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_COLOR_FormatYUV420PackedPlanar
23510d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar
23520d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_COLOR_FormatYUV420PackedSemiPlanar
23530d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar) {
23540d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            break;
23550d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
23560d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        // find best legacy non-standard format
23570d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        OMX_U32 flexibleEquivalent;
23580d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (legacyFormat.eColorFormat == OMX_COLOR_FormatUnused
23590d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && isFlexibleColorFormat(
23600d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        mOMX, mNode, format.eColorFormat, false /* usingNativeBuffers */,
23610d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        &flexibleEquivalent)
23620d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && flexibleEquivalent == OMX_COLOR_FormatYUV420Flexible) {
23630d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            memcpy(&legacyFormat, &format, sizeof(format));
23640d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
23650d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    }
2366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mOMX->setParameter(
2367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
2368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
2369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2371e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic const struct VideoCodingMapEntry {
2372e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    const char *mMime;
2373e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    OMX_VIDEO_CODINGTYPE mVideoCodingType;
2374e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber} kVideoCodingMapEntry[] = {
2375e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC },
23762472b1c0d63454e5d90a982bd6c555de6c3127bdRachad    { MEDIA_MIMETYPE_VIDEO_HEVC, OMX_VIDEO_CodingHEVC },
2377e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 },
2378e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 },
2379e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 },
238094705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 },
238194705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 },
2382e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber};
2383e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
23845778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic status_t GetVideoCodingTypeFromMime(
23855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
2386e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
2387e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
2388e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
2389e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) {
2390e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *codingType = kVideoCodingMapEntry[i].mVideoCodingType;
2391e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
2392e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
2393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2395e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    *codingType = OMX_VIDEO_CodingUnused;
2396e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2397e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
2398e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
2399e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2400e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic status_t GetMimeTypeForVideoCoding(
2401e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        OMX_VIDEO_CODINGTYPE codingType, AString *mime) {
2402e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
2403e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
2404e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
2405e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) {
2406e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *mime = kVideoCodingMapEntry[i].mMime;
2407e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
2408e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
2409e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
2410e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2411e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    mime->clear();
2412e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2413e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
24145778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
24155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24165778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoDecoder(
24170d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        const char *mime, const sp<AMessage> &msg, bool haveNativeWindow) {
241889869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    int32_t width, height;
241989869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    if (!msg->findInt32("width", &width)
242089869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            || !msg->findInt32("height", &height)) {
242189869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        return INVALID_OPERATION;
242289869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    }
242389869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar
24245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
24255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
24265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
24285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
24295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
2432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
2433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
243889869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    int32_t tmp;
243989869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    if (msg->findInt32("color-format", &tmp)) {
244089869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        OMX_COLOR_FORMATTYPE colorFormat =
244189869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            static_cast<OMX_COLOR_FORMATTYPE>(tmp);
244289869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        err = setVideoPortFormatType(
24430d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                kPortIndexOutput, OMX_VIDEO_CodingUnused, colorFormat, haveNativeWindow);
244489869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        if (err != OK) {
244589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            ALOGW("[%s] does not support color format %d",
244689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar                  mComponentName.c_str(), colorFormat);
24470d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            err = setSupportedOutputFormat(!haveNativeWindow /* getLegacyFlexibleFormat */);
244889869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        }
244989869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    } else {
24500d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        err = setSupportedOutputFormat(!haveNativeWindow /* getLegacyFlexibleFormat */);
245189869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    }
2452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
245778b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    int32_t frameRateInt;
245878b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    float frameRateFloat;
245978b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    if (!msg->findFloat("frame-rate", &frameRateFloat)) {
246078b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        if (!msg->findInt32("frame-rate", &frameRateInt)) {
246178b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            frameRateInt = -1;
246278b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        }
246378b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        frameRateFloat = (float)frameRateInt;
246478b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    }
246578b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad
2466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
246778b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            kPortIndexInput, width, height, compressionFormat, frameRateFloat);
2468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
2474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
2475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
24835778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) {
24845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
24855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("color-format", &tmp)) {
24865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
24875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_COLOR_FORMATTYPE colorFormat =
24905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        static_cast<OMX_COLOR_FORMATTYPE>(tmp);
24915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setVideoPortFormatType(
24935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
24945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
24965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support color format %d",
24975778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str(), colorFormat);
24985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
25005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Input port configuration */
25035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
25055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&def);
25065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
25085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexInput;
25105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
25125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
25135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
25155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
25165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t width, height, bitrate;
25195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("width", &width)
25205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("height", &height)
25215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("bitrate", &bitrate)) {
25225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
25235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
25265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
25275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t stride;
25295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("stride", &stride)) {
25305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        stride = width;
25315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nStride = stride;
25345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t sliceHeight;
25365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("slice-height", &sliceHeight)) {
25375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sliceHeight = height;
25385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nSliceHeight = sliceHeight;
25415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
25435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
25455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
25465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
25475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
25485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
25495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
25505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
25512c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        mTimePerFrameUs = (int64_t) (1000000.0f / frameRate);
25525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
25555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
2556a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    // this is redundant as it was already set up in setVideoPortFormatType
2557a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    // FIXME for now skip this only for flexible YUV formats
2558a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    if (colorFormat != OMX_COLOR_FormatYUV420Flexible) {
2559a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar        video_def->eColorFormat = colorFormat;
2560a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    }
25615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
25635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
25645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
25665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set input port definition parameters.",
25675778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
25685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
25705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Output port configuration */
25735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
25755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
25765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
25785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
25795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
25825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
25835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
25855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support compression format %d",
25865778822d86b0337407514b9372562b86edfa91cdAndreas Huber             mComponentName.c_str(), compressionFormat);
25875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
25895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexOutput;
25925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
25945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
25955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
25975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
25985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
26015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
26025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = 0;
26035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nBitrate = bitrate;
26045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = compressionFormat;
26055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = OMX_COLOR_FormatUnused;
26065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
26085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
26095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
26115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set output port definition parameters.",
26125778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
26135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
26155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (compressionFormat) {
26185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingMPEG4:
26195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupMPEG4EncoderParameters(msg);
26205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
26215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingH263:
26235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupH263EncoderParameters(msg);
26245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
26255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingAVC:
26275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupAVCEncoderParameters(msg);
26285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
26295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2630c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        case OMX_VIDEO_CodingHEVC:
2631c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            err = setupHEVCEncoderParameters(msg);
2632c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            break;
2633c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
263489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP8:
263589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP9:
263689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            err = setupVPXEncoderParameters(msg);
263789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            break;
263889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
26395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
26405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
26415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGI("setupVideoEncoder succeeded");
26445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
26465778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
26475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26480dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dongstatus_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) {
26490dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    OMX_VIDEO_PARAM_INTRAREFRESHTYPE params;
26500dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    InitOMXParams(&params);
26510dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.nPortIndex = kPortIndexOutput;
26520dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
26530dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode);
26540dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
26550dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic ||
26560dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
26570dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
26580dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) {
26590dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
26600dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
26610dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nCirMBs = mbs;
26620dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
26630dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
26640dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive ||
26650dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
26660dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
26670dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) {
26680dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
26690dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
26700dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirMBs = mbs;
26710dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
26720dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t ref;
26730dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) {
26740dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
26750dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
26760dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirRef = ref;
26770dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
26780dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
26790dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = mOMX->setParameter(
26800dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            mNode, OMX_IndexParamVideoIntraRefresh,
26810dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            &params, sizeof(params));
26820dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    return err;
26830dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong}
26840dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
26855778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
26865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (iFramesInterval < 0) {
26875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0xFFFFFFFF;
26885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (iFramesInterval == 0) {
26895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0;
26905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_U32 ret = frameRate * iFramesInterval;
26925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return ret;
26935778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
26945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
269596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatic OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) {
269696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    int32_t tmp;
269796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    if (!msg->findInt32("bitrate-mode", &tmp)) {
269896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        return OMX_Video_ControlRateVariable;
269996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    }
270096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
270196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp);
270296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber}
270396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
27045778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
27055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
27065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
27075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
27085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
27095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
271196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
271296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
27135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
27145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
27155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
27165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
27175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
27185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
27195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
27205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
27235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&mpeg4type);
27245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPortIndex = kPortIndexOutput;
27255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
27275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
27285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
27305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
27315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nSliceHeaderSpacing = 0;
27345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bSVH = OMX_FALSE;
27355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bGov = OMX_FALSE;
27365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nAllowedPictureTypes =
27385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
27395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
27415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mpeg4type.nPFrames == 0) {
27425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
27435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nBFrames = 0;
27455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nIDCVLCThreshold = 0;
27465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bACPred = OMX_TRUE;
27475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nMaxPacketSize = 256;
27485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nTimeIncRes = 1000;
27495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nHeaderExtension = 0;
27505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bReversibleVLC = OMX_FALSE;
27515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
27535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
27545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
27555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
27565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
27575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
27585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
27605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
27625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
27635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
27645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
27665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
27675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
27705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
27715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
27735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
27745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
277696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
27775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
27795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
27805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
27835778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
27845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27855778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
27865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
27875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
27885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
27895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
27905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
279296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
279396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
27945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
27955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
27965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
27975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
27985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
27995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
28005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
28015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_H263TYPE h263type;
28045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h263type);
28055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPortIndex = kPortIndexOutput;
28065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
28085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
28095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
28115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
28125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nAllowedPictureTypes =
28155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
28165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
28185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h263type.nPFrames == 0) {
28195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
28205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nBFrames = 0;
28225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
28245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
28255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
28265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
28275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
28285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
28295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
28315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
28335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
28345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
28355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
28375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
28385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bPLUSPTYPEAllowed = OMX_FALSE;
28415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bForceRoundingTypeToZero = OMX_FALSE;
28425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPictureHeaderRepetition = 0;
28435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nGOBHeaderInterval = 0;
28445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
28465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
28475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
28495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
28505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
285296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
28535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
28555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
28565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
28595778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
28605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2861a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar// static
2862a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnarint /* OMX_VIDEO_AVCLEVELTYPE */ ACodec::getAVCLevelFor(
2863a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        int width, int height, int rate, int bitrate,
2864a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        OMX_VIDEO_AVCPROFILETYPE profile) {
2865a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    // convert bitrate to main/baseline profile kbps equivalent
2866a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    switch (profile) {
2867a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        case OMX_VIDEO_AVCProfileHigh10:
2868a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 3000); break;
2869a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        case OMX_VIDEO_AVCProfileHigh:
2870a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 1250); break;
2871a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        default:
2872a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 1000); break;
2873a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    }
2874a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
2875a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    // convert size and rate to MBs
2876a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    width = divUp(width, 16);
2877a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    height = divUp(height, 16);
2878a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    int mbs = width * height;
2879a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    rate *= mbs;
2880a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    int maxDimension = max(width, height);
2881a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
2882a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    static const int limits[][5] = {
2883a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        /*   MBps     MB   dim  bitrate        level */
2884a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    1485,    99,  28,     64, OMX_VIDEO_AVCLevel1  },
2885a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    1485,    99,  28,    128, OMX_VIDEO_AVCLevel1b },
2886a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    3000,   396,  56,    192, OMX_VIDEO_AVCLevel11 },
2887a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    6000,   396,  56,    384, OMX_VIDEO_AVCLevel12 },
2888a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   11880,   396,  56,    768, OMX_VIDEO_AVCLevel13 },
2889a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   11880,   396,  56,   2000, OMX_VIDEO_AVCLevel2  },
2890a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   19800,   792,  79,   4000, OMX_VIDEO_AVCLevel21 },
2891a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   20250,  1620, 113,   4000, OMX_VIDEO_AVCLevel22 },
2892a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   40500,  1620, 113,  10000, OMX_VIDEO_AVCLevel3  },
2893a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  108000,  3600, 169,  14000, OMX_VIDEO_AVCLevel31 },
2894a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  216000,  5120, 202,  20000, OMX_VIDEO_AVCLevel32 },
2895a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  245760,  8192, 256,  20000, OMX_VIDEO_AVCLevel4  },
2896a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  245760,  8192, 256,  50000, OMX_VIDEO_AVCLevel41 },
2897a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  522240,  8704, 263,  50000, OMX_VIDEO_AVCLevel42 },
2898a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  589824, 22080, 420, 135000, OMX_VIDEO_AVCLevel5  },
2899a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  983040, 36864, 543, 240000, OMX_VIDEO_AVCLevel51 },
2900a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        { 2073600, 36864, 543, 240000, OMX_VIDEO_AVCLevel52 },
2901a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    };
2902a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
2903a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    for (size_t i = 0; i < ARRAY_SIZE(limits); i++) {
2904a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        const int (&limit)[5] = limits[i];
2905a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        if (rate <= limit[0] && mbs <= limit[1] && maxDimension <= limit[2]
2906a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar                && bitrate <= limit[3]) {
2907a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            return limit[4];
2908a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        }
2909a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    }
2910a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    return 0;
2911a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar}
2912a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
29135778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
29145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
29155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
29165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
29175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
29185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
292096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
292196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
29225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
29235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
29245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
29255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
29265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
29275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
29285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
29295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29310dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = OK;
29320dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    int32_t intraRefreshMode = 0;
29330dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) {
29340dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode);
29350dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (err != OK) {
29360dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
29370dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong                    err, intraRefreshMode);
29380dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return err;
29390dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
29400dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
29410dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
29425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_AVCTYPE h264type;
29435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h264type);
29445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nPortIndex = kPortIndexOutput;
29455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29460dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    err = mOMX->getParameter(
29475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
29485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
29505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
29515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nAllowedPictureTypes =
29545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
29555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
29575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
29585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
29595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
29605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
29615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
29625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
29645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
29665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
29675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
29685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
29705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
29715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // XXX
29747c25df82dfc8bbedb58608242f0d923a4594bb14James Dong    if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) {
29757c25df82dfc8bbedb58608242f0d923a4594bb14James Dong        ALOGW("Use baseline profile instead of %d for AVC recording",
29767c25df82dfc8bbedb58608242f0d923a4594bb14James Dong            h264type.eProfile);
29775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
29785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
29815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nSliceHeaderSpacing = 0;
29825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bUseHadamard = OMX_TRUE;
29835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefFrames = 1;
29845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nBFrames = 0;
29855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
29865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (h264type.nPFrames == 0) {
29875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
29885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
29895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx10ActiveMinus1 = 0;
29905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx11ActiveMinus1 = 0;
29915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bEntropyCodingCABAC = OMX_FALSE;
29925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bWeightedPPrediction = OMX_FALSE;
29935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bconstIpred = OMX_FALSE;
29945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirect8x8Inference = OMX_FALSE;
29955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirectSpatialTemporal = OMX_FALSE;
29965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nCabacInitIdc = 0;
29975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.nBFrames != 0) {
30005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
30015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
30025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableUEP = OMX_FALSE;
30045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableFMO = OMX_FALSE;
30055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableASO = OMX_FALSE;
30065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableRS = OMX_FALSE;
30075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bFrameMBsOnly = OMX_TRUE;
30085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bMBAFF = OMX_FALSE;
30095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
30105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
30125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
30135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
30155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
30165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
30175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
301896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return configureBitrate(bitrate, bitrateMode);
30195778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
30205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3021c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachadstatus_t ACodec::setupHEVCEncoderParameters(const sp<AMessage> &msg) {
3022c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    int32_t bitrate, iFrameInterval;
3023c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findInt32("bitrate", &bitrate)
3024c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
3025c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return INVALID_OPERATION;
3026c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
3027c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3028c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
3029c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3030c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    float frameRate;
3031c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findFloat("frame-rate", &frameRate)) {
3032c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t tmp;
3033c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("frame-rate", &tmp)) {
3034c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
3035c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
3036c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        frameRate = (float)tmp;
3037c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
3038c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3039c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_PARAM_HEVCTYPE hevcType;
3040c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    InitOMXParams(&hevcType);
3041c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    hevcType.nPortIndex = kPortIndexOutput;
3042c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3043c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    status_t err = OK;
3044c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    err = mOMX->getParameter(
3045c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
3046c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
3047c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
3048c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
3049c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3050c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    int32_t profile;
3051c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (msg->findInt32("profile", &profile)) {
3052c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t level;
3053c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("level", &level)) {
3054c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
3055c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
3056c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3057c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        err = verifySupportForProfileAndLevel(profile, level);
3058c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (err != OK) {
3059c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return err;
3060c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
3061c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3062c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eProfile = static_cast<OMX_VIDEO_HEVCPROFILETYPE>(profile);
3063c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eLevel = static_cast<OMX_VIDEO_HEVCLEVELTYPE>(level);
3064c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
3065c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3066c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    // TODO: Need OMX structure definition for setting iFrameInterval
3067c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3068c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    err = mOMX->setParameter(
3069c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
3070c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
3071c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
3072c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
3073c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3074c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    return configureBitrate(bitrate, bitrateMode);
3075c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad}
3076c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
307789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huberstatus_t ACodec::setupVPXEncoderParameters(const sp<AMessage> &msg) {
307889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    int32_t bitrate;
30794154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    int32_t iFrameInterval = 0;
30804154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    size_t tsLayers = 0;
30814154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE pattern =
30824154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        OMX_VIDEO_VPXTemporalLayerPatternNone;
30834154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    static const uint32_t kVp8LayerRateAlloction
30844154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS]
30854154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS] = {
30864154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        {100, 100, 100},  // 1 layer
30874154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 60, 100, 100},  // 2 layers {60%, 40%}
30884154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 40,  60, 100},  // 3 layers {40%, 20%, 40%}
30894154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    };
309089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    if (!msg->findInt32("bitrate", &bitrate)) {
309189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        return INVALID_OPERATION;
309289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    }
30934154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    msg->findInt32("i-frame-interval", &iFrameInterval);
309489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
309589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
309689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
30974154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    float frameRate;
30984154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (!msg->findFloat("frame-rate", &frameRate)) {
30994154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        int32_t tmp;
31004154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (!msg->findInt32("frame-rate", &tmp)) {
31014154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            return INVALID_OPERATION;
31024154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
31034154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        frameRate = (float)tmp;
31044154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
31054154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
31064154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    AString tsSchema;
31074154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (msg->findString("ts-schema", &tsSchema)) {
31084154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (tsSchema == "webrtc.vp8.1-layer") {
31094154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
31104154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 1;
31114154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else if (tsSchema == "webrtc.vp8.2-layer") {
31124154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
31134154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 2;
31144154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else if (tsSchema == "webrtc.vp8.3-layer") {
31154154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
31164154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 3;
31174154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else {
31184154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            ALOGW("Unsupported ts-schema [%s]", tsSchema.c_str());
31194154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
31204154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
31214154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
31224154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
31234154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    InitOMXParams(&vp8type);
31244154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    vp8type.nPortIndex = kPortIndexOutput;
31254154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    status_t err = mOMX->getParameter(
31264154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
31274154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            &vp8type, sizeof(vp8type));
31284154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
31294154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (err == OK) {
31304154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (iFrameInterval > 0) {
31314154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nKeyFrameInterval = setPFramesSpacing(iFrameInterval, frameRate);
31324154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
31334154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.eTemporalPattern = pattern;
31344154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.nTemporalLayerCount = tsLayers;
31354154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (tsLayers > 0) {
31364154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            for (size_t i = 0; i < OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS; i++) {
31374154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                vp8type.nTemporalLayerBitrateRatio[i] =
31384154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                    kVp8LayerRateAlloction[tsLayers - 1][i];
31394154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            }
31404154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
31414154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (bitrateMode == OMX_Video_ControlRateConstant) {
31424154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMinQuantizer = 2;
31434154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMaxQuantizer = 63;
31444154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
31454154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
31464154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        err = mOMX->setParameter(
31474154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
31484154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                &vp8type, sizeof(vp8type));
31494154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (err != OK) {
31504154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            ALOGW("Extended VP8 parameters set failed: %d", err);
31514154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
31524154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
31534154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
315489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    return configureBitrate(bitrate, bitrateMode);
315589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber}
315689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
31575778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::verifySupportForProfileAndLevel(
31585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t profile, int32_t level) {
31595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
31605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&params);
31615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    params.nPortIndex = kPortIndexOutput;
31625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (params.nProfileIndex = 0;; ++params.nProfileIndex) {
31645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
31655778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode,
31665778822d86b0337407514b9372562b86edfa91cdAndreas Huber                OMX_IndexParamVideoProfileLevelQuerySupported,
31675778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &params,
31685778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sizeof(params));
31695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
31715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
31725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
31735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
31755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
31765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (profile == supportedProfile && level <= supportedLevel) {
31785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OK;
31795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
31805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
31815778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
31825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
318396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatus_t ACodec::configureBitrate(
318496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) {
31855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
31865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&bitrateType);
31875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
31885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
31905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
31915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
31925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
31945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
31955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
31965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
319796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    bitrateType.eControlRate = bitrateMode;
31985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nTargetBitrate = bitrate;
31995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
32015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
32025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
32035778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
32045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32055778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupErrorCorrectionParameters() {
32065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
32075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&errorCorrectionType);
32085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nPortIndex = kPortIndexOutput;
32095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
32115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
32125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
32135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
32155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OK;  // Optional feature. Ignore this failure
32165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
32175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableHEC = OMX_FALSE;
32195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableResync = OMX_TRUE;
32205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nResynchMarkerSpacing = 256;
32215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
32225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableRVLC = OMX_FALSE;
32235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
32255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
32265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
32275778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
32285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3229f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoFormatOnPort(
3230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
323178b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat,
323278b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        float frameRate) {
3233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
3234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
3235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
3236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
3238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
3240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
3241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
3243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
3245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // XXX Need a (much) better heuristic to compute input buffer sizes.
3246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const size_t X = 64 * 1024;
3247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (def.nBufferSize < X) {
3248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.nBufferSize = X;
3249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
3253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameWidth = width;
3255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameHeight = height;
3256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
3258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eCompressionFormat = compressionFormat;
3259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eColorFormat = OMX_COLOR_FormatUnused;
326078b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        if (frameRate >= 0) {
326178b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
326278b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        }
3263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
3266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
3267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
3269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3271f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::initNativeWindow() {
3272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL) {
3273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
3274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
3277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
3278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3280d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Hubersize_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
3281d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    size_t n = 0;
3282d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
3283d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
3284d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        const BufferInfo &info = mBuffers[portIndex].itemAt(i);
3285d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
3286d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
3287d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            ++n;
3288d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        }
3289d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    }
3290d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
3291d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    return n;
3292d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber}
3293d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
32947e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubersize_t ACodec::countBuffersOwnedByNativeWindow() const {
32957e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    size_t n = 0;
32967e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
32977e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
32987e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
32997e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
33007e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
33017e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            ++n;
33027e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        }
33037e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
33047e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
33057e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    return n;
33067e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
33077e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
33087e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubervoid ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
33097e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (mNativeWindow == NULL) {
33107e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        return;
33117e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
33127e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
3313e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    while (countBuffersOwnedByNativeWindow() > mNumUndequeuedBuffers
33147e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            && dequeueBufferFromNativeWindow() != NULL) {
3315c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        // these buffers will be submitted as regular buffers; account for this
3316c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        if (mStoreMetaDataInOutputBuffers && mMetaDataBuffersToSubmit > 0) {
3317c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar            --mMetaDataBuffersToSubmit;
3318c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        }
33197e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
33207e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
33217e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
3322f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs(
3323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
3324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
3325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
3326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus != BufferInfo::OWNED_BY_US
3328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3329609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGV("[%s] Buffer %u on port %u still has status %d",
3330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mComponentName.c_str(),
3331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info->mBufferID, portIndex, info->mStatus);
3332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
3333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3339f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs() {
3340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return allYourBuffersAreBelongToUs(kPortIndexInput)
3341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        && allYourBuffersAreBelongToUs(kPortIndexOutput);
3342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3344f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::deferMessage(const sp<AMessage> &msg) {
3345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.push_back(msg);
3346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3348f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::processDeferredMessages() {
3349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> > queue = mDeferredQueue;
3350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.clear();
3351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> >::iterator it = queue.begin();
3353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while (it != queue.end()) {
3354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        onMessageReceived(*it++);
3355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
335803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar// static
3359229d242665c612fd97431d1e7ac004823b47f181Lajos Molnarbool ACodec::describeDefaultColorFormat(DescribeColorFormatParams &params) {
336003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    MediaImage &image = params.sMediaImage;
336103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    memset(&image, 0, sizeof(image));
336203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
336303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mType = MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
336403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mNumPlanes = 0;
336503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
336603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    const OMX_COLOR_FORMATTYPE fmt = params.eColorFormat;
336703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mWidth = params.nFrameWidth;
336803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mHeight = params.nFrameHeight;
336903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
337003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    // only supporting YUV420
337103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    if (fmt != OMX_COLOR_FormatYUV420Planar &&
337203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        fmt != OMX_COLOR_FormatYUV420PackedPlanar &&
337303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        fmt != OMX_COLOR_FormatYUV420SemiPlanar &&
33745a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        fmt != OMX_COLOR_FormatYUV420PackedSemiPlanar &&
33755a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        fmt != HAL_PIXEL_FORMAT_YV12) {
337603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        ALOGW("do not know color format 0x%x = %d", fmt, fmt);
3377229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return false;
337803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    }
337903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
3380b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    // TEMPORARY FIX for some vendors that advertise sliceHeight as 0
3381b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    if (params.nStride != 0 && params.nSliceHeight == 0) {
3382b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        ALOGW("using sliceHeight=%u instead of what codec advertised (=0)",
3383b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar                params.nFrameHeight);
3384b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        params.nSliceHeight = params.nFrameHeight;
3385b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    }
3386b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar
3387b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    // we need stride and slice-height to be non-zero
3388b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    if (params.nStride == 0 || params.nSliceHeight == 0) {
3389b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        ALOGW("cannot describe color format 0x%x = %d with stride=%u and sliceHeight=%u",
3390b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar                fmt, fmt, params.nStride, params.nSliceHeight);
3391b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        return false;
3392b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    }
3393b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar
339403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    // set-up YUV format
339503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mType = MediaImage::MEDIA_IMAGE_TYPE_YUV;
339603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mNumPlanes = 3;
339703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mBitDepth = 8;
339803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mOffset = 0;
339903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mColInc = 1;
340003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mRowInc = params.nStride;
340103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mHorizSubsampling = 1;
340203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mVertSubsampling = 1;
340303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
34045a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar    switch ((int)fmt) {
34055a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        case HAL_PIXEL_FORMAT_YV12:
34065a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            if (params.bUsingNativeBuffers) {
34075a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                size_t ystride = align(params.nStride, 16);
34085a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                size_t cstride = align(params.nStride / 2, 16);
34095a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.Y].mRowInc = ystride;
34105a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
34115a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mOffset = ystride * params.nSliceHeight;
34125a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mColInc = 1;
34135a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mRowInc = cstride;
34145a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mHorizSubsampling = 2;
34155a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mVertSubsampling = 2;
34165a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
34175a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mOffset = image.mPlane[image.V].mOffset
34185a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                        + (cstride * params.nSliceHeight / 2);
34195a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mColInc = 1;
34205a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mRowInc = cstride;
34215a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mHorizSubsampling = 2;
34225a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mVertSubsampling = 2;
34235a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                break;
34245a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            } else {
34255a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                // fall through as YV12 is used for YUV420Planar by some codecs
34265a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            }
34275a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
34285a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        case OMX_COLOR_FormatYUV420Planar:
342903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420PackedPlanar:
343003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight;
343103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mColInc = 1;
343203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mRowInc = params.nStride / 2;
343303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mHorizSubsampling = 2;
343403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mVertSubsampling = 2;
343503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
343603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset
343703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    + (params.nStride * params.nSliceHeight / 4);
343803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mColInc = 1;
343903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mRowInc = params.nStride / 2;
344003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mHorizSubsampling = 2;
344103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mVertSubsampling = 2;
344203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            break;
344303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
344403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420SemiPlanar:
344503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            // FIXME: NV21 for sw-encoder, NV12 for decoder and hw-encoder
344603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420PackedSemiPlanar:
344703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            // NV12
344803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight;
344903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mColInc = 2;
345003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mRowInc = params.nStride;
345103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mHorizSubsampling = 2;
345203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mVertSubsampling = 2;
345303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
345403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset + 1;
345503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mColInc = 2;
345603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mRowInc = params.nStride;
345703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mHorizSubsampling = 2;
345803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mVertSubsampling = 2;
345903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            break;
346003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
346103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        default:
346203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            TRESPASS();
346303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    }
3464229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    return true;
3465229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar}
3466229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3467229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar// static
3468229d242665c612fd97431d1e7ac004823b47f181Lajos Molnarbool ACodec::describeColorFormat(
3469229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        const sp<IOMX> &omx, IOMX::node_id node,
3470229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        DescribeColorFormatParams &describeParams)
3471229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar{
3472229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    OMX_INDEXTYPE describeColorFormatIndex;
3473229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    if (omx->getExtensionIndex(
3474229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            node, "OMX.google.android.index.describeColorFormat",
3475229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            &describeColorFormatIndex) != OK ||
3476229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        omx->getParameter(
3477229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            node, describeColorFormatIndex,
3478229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            &describeParams, sizeof(describeParams)) != OK) {
3479229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return describeDefaultColorFormat(describeParams);
3480229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    }
3481229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    return describeParams.sMediaImage.mType !=
3482229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
3483229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar}
3484229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3485229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar// static
3486229d242665c612fd97431d1e7ac004823b47f181Lajos Molnarbool ACodec::isFlexibleColorFormat(
3487229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar         const sp<IOMX> &omx, IOMX::node_id node,
34880d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar         uint32_t colorFormat, bool usingNativeBuffers, OMX_U32 *flexibleEquivalent) {
3489229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    DescribeColorFormatParams describeParams;
3490229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    InitOMXParams(&describeParams);
3491229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.eColorFormat = (OMX_COLOR_FORMATTYPE)colorFormat;
3492229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    // reasonable dummy values
3493229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nFrameWidth = 128;
3494229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nFrameHeight = 128;
3495229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nStride = 128;
3496229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nSliceHeight = 128;
34970d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    describeParams.bUsingNativeBuffers = (OMX_BOOL)usingNativeBuffers;
3498229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3499229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    CHECK(flexibleEquivalent != NULL);
3500229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3501229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    if (!describeColorFormat(omx, node, describeParams)) {
3502229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return false;
3503229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    }
3504229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3505229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    const MediaImage &img = describeParams.sMediaImage;
3506229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    if (img.mType == MediaImage::MEDIA_IMAGE_TYPE_YUV) {
3507229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        if (img.mNumPlanes != 3 ||
3508229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            img.mPlane[img.Y].mHorizSubsampling != 1 ||
3509229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            img.mPlane[img.Y].mVertSubsampling != 1) {
3510229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            return false;
3511229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
3512229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3513229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        // YUV 420
3514229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        if (img.mPlane[img.U].mHorizSubsampling == 2
3515229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.U].mVertSubsampling == 2
3516229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.V].mHorizSubsampling == 2
3517229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.V].mVertSubsampling == 2) {
3518229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            // possible flexible YUV420 format
3519229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            if (img.mBitDepth <= 8) {
3520229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar               *flexibleEquivalent = OMX_COLOR_FormatYUV420Flexible;
3521229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar               return true;
3522229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            }
3523229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
3524229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    }
3525229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    return false;
352603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar}
352703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
3528e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarstatus_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> &notify) {
3529e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    // TODO: catch errors an return them instead of using CHECK
353031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
353131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    InitOMXParams(&def);
3532e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    def.nPortIndex = portIndex;
353331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
353431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ(mOMX->getParameter(
353531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)),
353631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber             (status_t)OK);
353731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3538e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ((int)def.eDir,
3539e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            (int)(portIndex == kPortIndexOutput ? OMX_DirOutput : OMX_DirInput));
354031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
354131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    switch (def.eDomain) {
354231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainVideo:
354331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
354431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
3545e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            switch ((int)videoDef->eCompressionFormat) {
3546e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_VIDEO_CodingUnused:
3547e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3548e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(mIsEncoder ^ (portIndex == kPortIndexOutput));
3549e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
3550e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3551e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("stride", videoDef->nStride);
3552e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("slice-height", videoDef->nSliceHeight);
3553e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("color-format", videoDef->eColorFormat);
3554e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
35550d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                    if (mNativeWindow == NULL) {
35560d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        DescribeColorFormatParams describeParams;
35570d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        InitOMXParams(&describeParams);
35580d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.eColorFormat = videoDef->eColorFormat;
35590d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nFrameWidth = videoDef->nFrameWidth;
35600d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nFrameHeight = videoDef->nFrameHeight;
35610d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nStride = videoDef->nStride;
35620d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nSliceHeight = videoDef->nSliceHeight;
35630d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.bUsingNativeBuffers = OMX_FALSE;
35640d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar
35650d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        if (describeColorFormat(mOMX, mNode, describeParams)) {
35660d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                            notify->setBuffer(
35670d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                    "image-data",
35680d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                    ABuffer::CreateAsCopy(
35690d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                            &describeParams.sMediaImage,
35700d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                            sizeof(describeParams.sMediaImage)));
35715a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
35725a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                            MediaImage *img = &describeParams.sMediaImage;
35735a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                            ALOGV("[%s] MediaImage { F(%zux%zu) @%zu+%zu+%zu @%zu+%zu+%zu @%zu+%zu+%zu }",
35745a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                                    mComponentName.c_str(), img->mWidth, img->mHeight,
35755a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                                    img->mPlane[0].mOffset, img->mPlane[0].mColInc, img->mPlane[0].mRowInc,
35765a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                                    img->mPlane[1].mOffset, img->mPlane[1].mColInc, img->mPlane[1].mRowInc,
35775a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                                    img->mPlane[2].mOffset, img->mPlane[2].mColInc, img->mPlane[2].mRowInc);
35780d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        }
357903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    }
358003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
358191a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                    if (portIndex != kPortIndexOutput) {
358291a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                        // TODO: also get input crop
358391a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                        break;
358491a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                    }
358591a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar
3586e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_CONFIG_RECTTYPE rect;
3587e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&rect);
358891a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                    rect.nPortIndex = portIndex;
3589e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3590e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    if (mOMX->getConfig(
359191a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                mNode,
359291a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                (portIndex == kPortIndexOutput ?
359391a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                        OMX_IndexConfigCommonOutputCrop :
359491a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                        OMX_IndexConfigCommonInputCrop),
3595e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &rect, sizeof(rect)) != OK) {
3596e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nLeft = 0;
3597e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nTop = 0;
3598e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nWidth = videoDef->nFrameWidth;
3599e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nHeight = videoDef->nFrameHeight;
3600e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    }
360131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3602e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nLeft, 0);
3603e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nTop, 0);
3604e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nWidth, 0u);
3605e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nHeight, 0u);
3606e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_LE(rect.nLeft + rect.nWidth - 1, videoDef->nFrameWidth);
3607e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_LE(rect.nTop + rect.nHeight - 1, videoDef->nFrameHeight);
3608e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3609e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setRect(
3610577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            "crop",
3611577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nLeft,
3612577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nTop,
3613e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                            rect.nLeft + rect.nWidth - 1,
3614e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                            rect.nTop + rect.nHeight - 1);
3615e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3616e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3617e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
36184730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
36194730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP8:
36204730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP9:
36214730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                {
36224730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
36234730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    InitOMXParams(&vp8type);
36244730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    vp8type.nPortIndex = kPortIndexOutput;
36254730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    status_t err = mOMX->getParameter(
36264730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            mNode,
36274730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
36284730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            &vp8type,
36294730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            sizeof(vp8type));
36304730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
36314730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    if (err == OK) {
36324730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        AString tsSchema = "none";
36334730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        if (vp8type.eTemporalPattern
36344730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                == OMX_VIDEO_VPXTemporalLayerPatternWebRTC) {
36354730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            switch (vp8type.nTemporalLayerCount) {
36364730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 1:
36374730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
36384730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.1-layer";
36394730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
36404730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
36414730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 2:
36424730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
36434730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.2-layer";
36444730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
36454730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
36464730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 3:
36474730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
36484730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.3-layer";
36494730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
36504730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
36514730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                default:
36524730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
36534730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
36544730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
36554730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            }
36564730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        }
36574730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        notify->setString("ts-schema", tsSchema);
36584730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    }
36594730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    // Fall through to set up mime.
36604730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                }
36614730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
3662e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                default:
3663e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3664e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(mIsEncoder ^ (portIndex == kPortIndexInput));
3665e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    AString mime;
3666e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    if (GetMimeTypeForVideoCoding(
3667e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        videoDef->eCompressionFormat, &mime) != OK) {
3668e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", "application/octet-stream");
3669e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    } else {
3670e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", mime.c_str());
3671e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    }
3672e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3673e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
367431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            }
3675e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("width", videoDef->nFrameWidth);
3676e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("height", videoDef->nFrameHeight);
36775a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            ALOGV("[%s] %s format is %s", mComponentName.c_str(),
36785a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                    portIndex == kPortIndexInput ? "input" : "output",
36795a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                    notify->debugString().c_str());
36805a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
368131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
368231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
368331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
368431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainAudio:
368531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
368631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
368731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
368897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            switch ((int)audioDef->eEncoding) {
3689e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingPCM:
3690e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3691e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_PCMMODETYPE params;
3692e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3693e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3694e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3695e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3696e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioPcm,
3697e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3698e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3699e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
370014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_GT(params.nChannels, 0);
3701e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK(params.nChannels == 1 || params.bInterleaved);
3702e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(params.nBitPerSample, 16u);
370314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
370414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.eNumData,
370514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_NumericalDataSigned);
370614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
370714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.ePCMMode,
370814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_AUDIO_PCMModeLinear);
3709e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3710e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
3711e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
3712e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSamplingRate);
3713e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3714e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mChannelMaskPresent) {
3715e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("channel-mask", mChannelMask);
37168b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                    }
3717e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
37188b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                }
37199806555d3930be43e11106281dee354820ac1c88Andreas Huber
3720e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAAC:
3721e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3722e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AACPROFILETYPE params;
3723e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3724e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3725e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3726e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3727e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAac,
3728e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3729e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3730e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3731e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
3732e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
3733e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
3734e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
3735e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
3736e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3737e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAMR:
3738e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3739e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AMRTYPE params;
3740e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3741e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
37429806555d3930be43e11106281dee354820ac1c88Andreas Huber
3743e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3744e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAmr,
3745e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3746e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3747e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3748e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", 1);
3749e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) {
3750e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
3751e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_WB);
3752e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3753e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 16000);
3754e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    } else {
3755e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
3756e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
3757e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3758e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 8000);
3759e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
3760e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
3761e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
3762e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3763e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingFLAC:
3764e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3765e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_FLACTYPE params;
3766e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3767e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3768e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3769e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3770e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioFlac,
3771e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3772e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3773e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3774e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC);
3775e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
3776e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
3777e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
3778e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
3779e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3780e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingMP3:
3781e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3782e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_MP3TYPE params;
3783e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
3784e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3785e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3786e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_EQ(mOMX->getParameter(
3787e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                mNode, OMX_IndexParamAudioMp3,
3788e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &params, sizeof(params)),
3789e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                             (status_t)OK);
3790e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3791e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MPEG);
3792e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
3793e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
3794e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3795e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
3796e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3797e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingVORBIS:
3798e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3799e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_VORBISTYPE params;
3800e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
3801e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3802e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3803e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_EQ(mOMX->getParameter(
3804e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                mNode, OMX_IndexParamAudioVorbis,
3805e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &params, sizeof(params)),
3806e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                             (status_t)OK);
3807e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3808e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_VORBIS);
3809e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
3810e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
3811e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3812e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
3813e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
381497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                case OMX_AUDIO_CodingAndroidAC3:
381597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                {
381697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    OMX_AUDIO_PARAM_ANDROID_AC3TYPE params;
381797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    InitOMXParams(&params);
3818e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
381997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
382097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    CHECK_EQ((status_t)OK, mOMX->getParameter(
382197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            mNode,
382297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
382397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            &params,
382497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            sizeof(params)));
382597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
382697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AC3);
382797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("channel-count", params.nChannels);
382897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("sample-rate", params.nSampleRate);
382997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    break;
383097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                }
3831e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
38328a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                case OMX_AUDIO_CodingAndroidEAC3:
38338a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                {
38348a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    OMX_AUDIO_PARAM_ANDROID_EAC3TYPE params;
38358a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    InitOMXParams(&params);
38368a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    params.nPortIndex = portIndex;
38378a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
38388a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    CHECK_EQ((status_t)OK, mOMX->getParameter(
38398a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                            mNode,
38408a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
38418a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                            &params,
38428a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                            sizeof(params)));
38438a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
38448a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_EAC3);
38458a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setInt32("channel-count", params.nChannels);
38468a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setInt32("sample-rate", params.nSampleRate);
38478a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    break;
38488a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                }
38498a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
38508c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                case OMX_AUDIO_CodingAndroidOPUS:
38518c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                {
38528c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    OMX_AUDIO_PARAM_ANDROID_OPUSTYPE params;
38538c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    InitOMXParams(&params);
38548c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    params.nPortIndex = portIndex;
38558c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
38568c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    CHECK_EQ((status_t)OK, mOMX->getParameter(
38578c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            mNode,
38588c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus,
38598c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            &params,
38608c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            sizeof(params)));
38618c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
38628c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_OPUS);
38638c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("channel-count", params.nChannels);
38648c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("sample-rate", params.nSampleRate);
38658c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    break;
38668c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                }
38678c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
386810d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                case OMX_AUDIO_CodingG711:
386910d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                {
387010d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    OMX_AUDIO_PARAM_PCMMODETYPE params;
387110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    InitOMXParams(&params);
387210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    params.nPortIndex = portIndex;
387310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
387410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    CHECK_EQ((status_t)OK, mOMX->getParameter(
387510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                            mNode,
387610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                            (OMX_INDEXTYPE)OMX_IndexParamAudioPcm,
387710d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                            &params,
387810d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                            sizeof(params)));
387910d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
388010d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    const char *mime = NULL;
388110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    if (params.ePCMMode == OMX_AUDIO_PCMModeMULaw) {
388210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_G711_MLAW;
388310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    } else if (params.ePCMMode == OMX_AUDIO_PCMModeALaw) {
388410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_G711_ALAW;
388510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    } else { // params.ePCMMode == OMX_AUDIO_PCMModeLinear
388610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_RAW;
388710d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    }
388810d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setString("mime", mime);
388910d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setInt32("channel-count", params.nChannels);
389010d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setInt32("sample-rate", params.nSamplingRate);
389110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    break;
389210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                }
389341d3f579d2c166984958263533284209b90c87d5Marco Nelissen
389441d3f579d2c166984958263533284209b90c87d5Marco Nelissen                case OMX_AUDIO_CodingGSMFR:
389541d3f579d2c166984958263533284209b90c87d5Marco Nelissen                {
389641d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    OMX_AUDIO_PARAM_MP3TYPE params;
389741d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    InitOMXParams(&params);
389841d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    params.nPortIndex = portIndex;
389941d3f579d2c166984958263533284209b90c87d5Marco Nelissen
390041d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    CHECK_EQ(mOMX->getParameter(
390141d3f579d2c166984958263533284209b90c87d5Marco Nelissen                                mNode, OMX_IndexParamAudioPcm,
390241d3f579d2c166984958263533284209b90c87d5Marco Nelissen                                &params, sizeof(params)),
390341d3f579d2c166984958263533284209b90c87d5Marco Nelissen                             (status_t)OK);
390441d3f579d2c166984958263533284209b90c87d5Marco Nelissen
390541d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MSGSM);
390641d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    notify->setInt32("channel-count", params.nChannels);
390741d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    notify->setInt32("sample-rate", params.nSampleRate);
390841d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    break;
390910d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                }
391010d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
3911e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                default:
3912e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    ALOGE("UNKNOWN AUDIO CODING: %d\n", audioDef->eEncoding);
3913e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    TRESPASS();
3914e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
391531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
391631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
391731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
391831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        default:
391931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            TRESPASS();
392031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    }
392131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3922e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    return OK;
3923e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar}
3924e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3925e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarvoid ACodec::sendFormatChange(const sp<AMessage> &reply) {
39264e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    sp<AMessage> notify = mBaseOutputFormat->dup();
3927e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    notify->setInt32("what", kWhatOutputFormatChanged);
3928e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3929e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ(getPortFormat(kPortIndexOutput, notify), (status_t)OK);
3930e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3931e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    AString mime;
3932e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK(notify->findString("mime", &mime));
3933e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3934e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    int32_t left, top, right, bottom;
3935e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if (mime == MEDIA_MIMETYPE_VIDEO_RAW &&
3936e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        mNativeWindow != NULL &&
3937e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->findRect("crop", &left, &top, &right, &bottom)) {
3938e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        // notify renderer of the crop change
3939e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        // NOTE: native window uses extended right-bottom coordinate
3940e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        reply->setRect("crop", left, top, right + 1, bottom + 1);
3941e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    } else if (mime == MEDIA_MIMETYPE_AUDIO_RAW &&
3942e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar               (mEncoderDelay || mEncoderPadding)) {
3943e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        int32_t channelCount;
3944e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        CHECK(notify->findInt32("channel-count", &channelCount));
3945e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        size_t frameSize = channelCount * sizeof(int16_t);
3946e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        if (mSkipCutBuffer != NULL) {
3947e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            size_t prevbufsize = mSkipCutBuffer->size();
3948e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            if (prevbufsize != 0) {
3949ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                ALOGW("Replacing SkipCutBuffer holding %zu bytes", prevbufsize);
3950e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            }
3951e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        }
3952e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        mSkipCutBuffer = new SkipCutBuffer(
3953e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                mEncoderDelay * frameSize,
3954e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                mEncoderPadding * frameSize);
3955e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
3956e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
395731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->post();
395831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
395931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mSentFormat = true;
396031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber}
396131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
39625778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
3963cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    sp<AMessage> notify = mNotify->dup();
3964d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatError);
3965251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    ALOGE("signalError(omxError %#x, internalError %d)", error, internalError);
3966251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
3967251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (internalError == UNKNOWN_ERROR) { // find better error code
3968251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        const status_t omxStatus = statusFromOMXError(error);
3969251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        if (omxStatus != 0) {
3970251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            internalError = omxStatus;
3971251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        } else {
3972251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            ALOGW("Invalid OMX error %#x", error);
3973251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        }
3974251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
39755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("err", internalError);
3976251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    notify->setInt32("actionCode", ACTION_CODE_FATAL); // could translate from OMX error.
3977cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->post();
3978cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber}
3979cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber
3980bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huberstatus_t ACodec::pushBlankBuffersToNativeWindow() {
3981bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    status_t err = NO_ERROR;
3982bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    ANativeWindowBuffer* anb = NULL;
3983bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int numBufs = 0;
3984bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int minUndequeuedBufs = 0;
3985bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3986bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We need to reconnect to the ANativeWindow as a CPU client to ensure that
3987bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // no frames get dropped by SurfaceFlinger assuming that these are video
3988bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // frames.
3989bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_disconnect(mNativeWindow.get(),
3990bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_MEDIA);
3991bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3992bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
3993bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3994bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
3995bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3996bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3997bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_connect(mNativeWindow.get(),
3998bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_CPU);
3999bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
4000bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
4001bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
4002bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
4003bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
4004bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4005ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    err = native_window_set_buffers_dimensions(mNativeWindow.get(), 1, 1);
4006ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    if (err != NO_ERROR) {
4007ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        ALOGE("error pushing blank frames: set_buffers_dimensions failed: %s (%d)",
4008ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                strerror(-err), -err);
4009ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        goto error;
4010ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    }
4011ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar
4012ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    err = native_window_set_buffers_format(mNativeWindow.get(), HAL_PIXEL_FORMAT_RGBX_8888);
4013bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
4014ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        ALOGE("error pushing blank frames: set_buffers_format failed: %s (%d)",
4015bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
4016bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
4017bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
4018bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
401987eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin    err = native_window_set_scaling_mode(mNativeWindow.get(),
402087eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
402187eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin    if (err != NO_ERROR) {
402287eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin        ALOGE("error pushing blank_frames: set_scaling_mode failed: %s (%d)",
402387eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin              strerror(-err), -err);
402487eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin        goto error;
4025bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
4026bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4027bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_usage(mNativeWindow.get(),
4028bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            GRALLOC_USAGE_SW_WRITE_OFTEN);
4029bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
4030bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_usage failed: %s (%d)",
4031bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
4032bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
4033bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
4034bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4035bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = mNativeWindow->query(mNativeWindow.get(),
4036bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs);
4037bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
4038bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: MIN_UNDEQUEUED_BUFFERS query "
4039bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                "failed: %s (%d)", strerror(-err), -err);
4040bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
4041bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
4042bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4043bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    numBufs = minUndequeuedBufs + 1;
4044bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffer_count(mNativeWindow.get(), numBufs);
4045bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
4046bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffer_count failed: %s (%d)",
4047bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
4048bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
4049bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
4050bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4051bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We  push numBufs + 1 buffers to ensure that we've drawn into the same
4052bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // buffer twice.  This should guarantee that the buffer has been displayed
4053bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // on the screen and then been replaced, so an previous video frames are
4054bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // guaranteed NOT to be currently displayed.
4055bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    for (int i = 0; i < numBufs + 1; i++) {
40561e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &anb);
4057bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
4058bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: dequeueBuffer failed: %s (%d)",
4059bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
4060bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
4061bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
4062bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4063bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
4064bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4065bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Fill the buffer with the a 1x1 checkerboard pattern ;)
4066bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        uint32_t* img = NULL;
4067bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
4068bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
4069bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: lock failed: %s (%d)",
4070bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
4071bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
4072bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
4073bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4074bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        *img = 0;
4075bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4076bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->unlock();
4077bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
4078bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: unlock failed: %s (%d)",
4079bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
4080bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
4081bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
4082bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4083bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->queueBuffer(mNativeWindow.get(),
40841e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                buf->getNativeBuffer(), -1);
4085bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
4086bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: queueBuffer failed: %s (%d)",
4087bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
4088bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
4089bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
4090bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4091bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        anb = NULL;
4092bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
4093bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4094bc098410be55f9d96f394b3981a0c482b83859b6Andreas Hubererror:
4095bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4096bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
4097bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after an error.
4098bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (anb != NULL) {
40991e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis            mNativeWindow->cancelBuffer(mNativeWindow.get(), anb, -1);
4100bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
4101bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4102bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_disconnect(mNativeWindow.get(),
4103bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
4104bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_connect(mNativeWindow.get(),
4105bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
4106bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4107bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
4108bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    } else {
4109bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after success.
4110bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_disconnect(mNativeWindow.get(),
4111bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
4112bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
4113bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
4114bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
4115bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
4116bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
4117bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4118bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_connect(mNativeWindow.get(),
4119bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
4120bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
4121bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
4122bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
4123bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
4124bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
4125bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4126bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return NO_ERROR;
4127bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
4128bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber}
4129bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4132eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberACodec::PortDescription::PortDescription() {
4133eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
4134eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4135496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t ACodec::requestIDRFrame() {
4136496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    if (!mIsEncoder) {
4137496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        return ERROR_UNSUPPORTED;
4138496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    }
4139496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4140496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    OMX_CONFIG_INTRAREFRESHVOPTYPE params;
4141496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    InitOMXParams(&params);
4142496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4143496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.nPortIndex = kPortIndexOutput;
4144496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.IntraRefreshVOP = OMX_TRUE;
4145496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4146496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    return mOMX->setConfig(
4147496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            mNode,
4148496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            OMX_IndexConfigVideoIntraVOPRefresh,
4149496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            &params,
4150496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            sizeof(params));
4151496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
4152496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4153eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubervoid ACodec::PortDescription::addBuffer(
4154eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        IOMX::buffer_id id, const sp<ABuffer> &buffer) {
4155eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBufferIDs.push_back(id);
4156eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBuffers.push_back(buffer);
4157eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
4158eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4159eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersize_t ACodec::PortDescription::countBuffers() {
4160eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.size();
4161eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
4162eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4163eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberIOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const {
4164eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.itemAt(index);
4165eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
4166eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4167eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const {
4168eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBuffers.itemAt(index);
4169eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
4170eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4171eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber////////////////////////////////////////////////////////////////////////////////
4172eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4173f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
4174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : AState(parentState),
4175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mCodec(codec) {
4176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4178ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas HuberACodec::BaseState::PortMode ACodec::BaseState::getPortMode(
4179ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
4180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return KEEP_BUFFERS;
4181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4183f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
4184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatInputBufferFilled:
4186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onInputBufferFilled(msg);
4188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatOutputBufferDrained:
4192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onOutputBufferDrained(msg);
4194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatOMXMessage:
4198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXMessage(msg);
4200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
42027cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
42037cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
42047cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
4205251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            // This may result in an app illegal state exception.
42067cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            ALOGE("Message 0x%x was not handled", msg->what());
42077cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
42087cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            return true;
42097cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
42107cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4211ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        case ACodec::kWhatOMXDied:
4212ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        {
4213251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            // This will result in kFlagSawMediaServerDie handling in MediaCodec.
4214ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            ALOGE("OMX/mediaserver died, signalling error!");
4215ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT);
4216ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            break;
4217ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        }
4218ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
421930358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        case ACodec::kWhatReleaseCodecInstance:
422030358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        {
422130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            ALOGI("[%s] forcing the release of codec",
422230358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar                    mCodec->mComponentName.c_str());
422330358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            status_t err = mCodec->mOMX->freeNode(mCodec->mNode);
422430358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            ALOGE_IF("[%s] failed to release codec instance: err=%d",
422530358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar                       mCodec->mComponentName.c_str(), err);
422630358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            sp<AMessage> notify = mCodec->mNotify->dup();
422730358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
422830358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            notify->post();
422930358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            break;
423030358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        }
423130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar
4232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
4234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4239f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
4240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t type;
4241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findInt32("type", &type));
4242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
42435e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // there is a possibility that this is an outstanding message for a
42445e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // codec that we have already destroyed
4245ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    if (mCodec->mNode == 0) {
42465e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar        ALOGI("ignoring message as already freed component: %s",
42475e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar                msg->debugString().c_str());
42485e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar        return true;
42495e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    }
42505e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar
4251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::node_id nodeID;
4252609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("node", (int32_t*)&nodeID));
4253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(nodeID, mCodec->mNode);
4254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (type) {
4256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EVENT:
4257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t event, data1, data2;
4259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("event", &event));
4260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data1", &data1));
4261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data2", &data2));
4262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
42630af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            if (event == OMX_EventCmdComplete
42640af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data1 == OMX_CommandFlush
42650af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data2 == (int32_t)OMX_ALL) {
42660af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // Use of this notification is not consistent across
42670af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // implementations. We'll drop this notification and rely
42680af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // on flush-complete notifications on the individual port
42690af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // indices instead.
42700af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
42710af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                return true;
42720af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            }
42730af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
4274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEvent(
4275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_EVENTTYPE>(event),
4276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data1),
4277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data2));
4278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EMPTY_BUFFER_DONE:
4281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
4283609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
4284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEmptyBufferDone(bufferID);
4286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::FILL_BUFFER_DONE:
4289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
4291609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
4292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t rangeOffset, rangeLength, flags;
4294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs;
4295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_offset", &rangeOffset));
4297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_length", &rangeLength));
4298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("flags", &flags));
4299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt64("timestamp", &timeUs));
4300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXFillBufferDone(
4302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    bufferID,
4303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (size_t)rangeOffset, (size_t)rangeLength,
4304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (OMX_U32)flags,
4305784e24e386b088c05d653ab482f2e95cb53e3d01Andy Hung                    timeUs);
4306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
4310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4314f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEvent(
4315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (event != OMX_EventError) {
4317ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        ALOGV("[%s] EVENT(%d, 0x%08x, 0x%08x)",
4318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mCodec->mComponentName.c_str(), event, data1, data2);
4319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return false;
4321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4323ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGE("[%s] ERROR(0x%08x)", mCodec->mComponentName.c_str(), data1);
4324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4325251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // verify OMX component sends back an error we expect.
4326251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    OMX_ERRORTYPE omxError = (OMX_ERRORTYPE)data1;
4327251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (!isOMXError(omxError)) {
4328251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        ALOGW("Invalid OMX error %#x", omxError);
4329251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        omxError = OMX_ErrorUndefined;
4330251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
4331251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    mCodec->signalError(omxError);
4332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4336f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID) {
4337ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGV("[%s] onOMXEmptyBufferDone %u",
4338349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber         mCodec->mComponentName.c_str(), bufferID);
4339349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
4341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexInput, bufferID);
4342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
4344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
4345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
434696e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // We're in "store-metadata-in-buffers" mode, the underlying
434796e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // OMX component had access to data that's implicitly refcounted
434896e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // by this "MediaBuffer" object. Now that the OMX component has
434996e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // told us that it's done with the input buffer, we can decrement
435096e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // the mediaBuffer's reference count.
435196e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    info->mData->setMediaBufferBase(NULL);
4352d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
4354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            postFillThisBuffer(info);
4361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
4366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();  // Not currently used
4367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4374f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
4375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
4376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
4377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
4380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
4382d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatFillThisBuffer);
4383609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    notify->setInt32("buffer-id", info->mBufferID);
4384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mData->meta()->clear();
43862d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    notify->setBuffer("buffer", info->mData);
4387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
43881d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec);
4389609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    reply->setInt32("buffer-id", info->mBufferID);
4390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setMessage("reply", reply);
4392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->post();
4394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
4396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4398f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
4399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
4400609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
44012d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    sp<ABuffer> buffer;
4402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t err = OK;
44035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool eos = false;
4404a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar    PortMode mode = getPortMode(kPortIndexInput);
44055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
44062d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    if (!msg->findBuffer("buffer", &buffer)) {
4407a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar        /* these are unfilled buffers returned by client */
4408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findInt32("err", &err));
4409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
44107fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        if (err == OK) {
44117fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            /* buffers with no errors are returned on MediaCodec.flush */
44127fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            mode = KEEP_BUFFERS;
44137fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        } else {
44147fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            ALOGV("[%s] saw error %d instead of an input buffer",
44157fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                 mCodec->mComponentName.c_str(), err);
44167fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            eos = true;
44177fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        }
44183831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
44192d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber        buffer.clear();
4420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
44225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
44235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
44245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
44255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = ERROR_END_OF_STREAM;
44265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
44275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
4429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_UPSTREAM);
4430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
4432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
44365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (eos) {
4437dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (!mCodec->mPortEOS[kPortIndexInput]) {
4438dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
4439dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mInputEOSResult = err;
4440dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
4441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
44475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
4448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int64_t timeUs;
4449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
4450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
4452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t isCSD;
4454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
4455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
4456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
4457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
44585778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (eos) {
44595778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    flags |= OMX_BUFFERFLAG_EOS;
44605778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
44615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer != info->mData) {
4463ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] Needs to copy input data for buffer %u. (%p != %p)",
4464d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(),
4465d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         bufferID,
4466d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         buffer.get(), info->mData.get());
4467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    CHECK_LE(buffer->size(), info->mData->capacity());
4469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    memcpy(info->mData->data(), buffer->data(), buffer->size());
4470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
4471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4472078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
4473ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] calling emptyBuffer %u w/ codec specific data",
4474078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID);
44755778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else if (flags & OMX_BUFFERFLAG_EOS) {
4476ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] calling emptyBuffer %u w/ EOS",
44775778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str(), bufferID);
4478078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                } else {
4479d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
4480ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGI("[%s] calling emptyBuffer %u w/ time %lld us",
4481ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                         mCodec->mComponentName.c_str(), bufferID, (long long)timeUs);
4482d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#else
4483ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] calling emptyBuffer %u w/ time %lld us",
4484ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                         mCodec->mComponentName.c_str(), bufferID, (long long)timeUs);
4485d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
4486078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                }
4487349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4488d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
4489d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ACodec::BufferStats stats;
4490d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
4491d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mFillBufferDoneTimeUs = -1ll;
4492d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mCodec->mBufferStats.add(timeUs, stats);
4493d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
4494d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4495054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                if (mCodec->mStoreMetaDataInOutputBuffers) {
4496054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    // try to submit an output buffer for each input buffer
4497054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    PortMode outputMode = getPortMode(kPortIndexOutput);
4498054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4499054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    ALOGV("MetaDataBuffersToSubmit=%u portMode=%s",
4500054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            mCodec->mMetaDataBuffersToSubmit,
4501054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            (outputMode == FREE_BUFFERS ? "FREE" :
4502054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                             outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
4503054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    if (outputMode == RESUBMIT_BUFFERS) {
4504e53350373ac516257b4f8956ff1e3f1ac48f607eLajos Molnar                        mCodec->submitOutputMetaDataBuffer();
4505054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    }
4506054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                }
4507054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
4509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
4510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
4511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
4512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            buffer->size(),
4513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            flags,
4514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            timeUs),
4515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
45195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (!eos) {
45205778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    getMoreInputDataIfPossible();
45215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
45225778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] Signalled EOS on the input port",
45235778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str());
45245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
45255778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
45265778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mInputEOSResult = err;
45275778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
4528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
4529dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (err != ERROR_END_OF_STREAM) {
45303856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port "
4531dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         "due to error %d",
4532dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str(), err);
4533dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                } else {
45343856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port",
4535dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str());
4536dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
4537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4538ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                ALOGV("[%s] calling emptyBuffer %u signalling EOS",
4539349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                     mCodec->mComponentName.c_str(), bufferID);
4540349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
4542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
4543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
4544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
4545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
4546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_BUFFERFLAG_EOS,
4547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0),
4548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexInput] = true;
4553dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                mCodec->mInputEOSResult = err;
4554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4557625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih
4558625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih        default:
4559625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
4560625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih            break;
4561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4564f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::getMoreInputDataIfPossible() {
4565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
4566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
4567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *eligible = NULL;
4570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
4572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
4573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
4575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
4576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // There's already a "read" pending.
4577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
4578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
4580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_US) {
4582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            eligible = info;
4583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (eligible == NULL) {
4587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
4588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(eligible);
4591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4593f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXFillBufferDone(
4594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferID,
4595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        size_t rangeOffset, size_t rangeLength,
4596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 flags,
4597784e24e386b088c05d653ab482f2e95cb53e3d01Andy Hung        int64_t timeUs) {
4598609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] onOMXFillBufferDone %u time %" PRId64 " us, flags = 0x%08x",
45995778822d86b0337407514b9372562b86edfa91cdAndreas Huber         mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
4600349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
4602d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4603d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
4604d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    index = mCodec->mBufferStats.indexOfKey(timeUs);
4605d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (index >= 0) {
4606d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
4607d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
4608d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4609d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ALOGI("frame PTS %lld: %lld",
4610d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                timeUs,
4611d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
4612d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4613d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mCodec->mBufferStats.removeItemsAt(index);
4614d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats = NULL;
4615d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
4616d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
4617d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
4619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
4620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
4622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4623054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mDequeuedAt = ++mCodec->mDequeueCounter;
4624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
4625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
4627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4634a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            if (rangeLength == 0 && (!(flags & OMX_BUFFERFLAG_EOS)
4635a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                    || mCodec->mPortEOS[kPortIndexOutput])) {
4636609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                ALOGV("[%s] calling fillBuffer %u",
46375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                     mCodec->mComponentName.c_str(), info->mBufferID);
4638349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
46395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK_EQ(mCodec->mOMX->fillBuffer(
46405778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mCodec->mNode, info->mBufferID),
46415778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         (status_t)OK);
4642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
46435778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
46445778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
46455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
464631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4647577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            sp<AMessage> reply =
46481d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar                new AMessage(kWhatOutputBufferDrained, mCodec);
4649577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
46504bdda35319d5f46efea2089b865c8a64816389cdMarco Nelissen            if (!mCodec->mSentFormat && rangeLength > 0) {
4651577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->sendFormatChange(reply);
46525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
4653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4654308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            if (mCodec->mUseMetadataOnEncoderOutput) {
4655308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                native_handle_t* handle =
4656308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        *(native_handle_t**)(info->mData->data() + 4);
4657308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setPointer("handle", handle);
4658308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeOffset", rangeOffset);
4659308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeLength", rangeLength);
4660308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            } else {
4661308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->setRange(rangeOffset, rangeLength);
4662308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            }
4663496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#if 0
466421ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen            if (mCodec->mNativeWindow == NULL) {
4665496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                if (IsIDR(info->mData)) {
4666496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                    ALOGI("IDR frame");
4667496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                }
46685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
466921ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen#endif
4670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
46718b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            if (mCodec->mSkipCutBuffer != NULL) {
46728b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                mCodec->mSkipCutBuffer->submit(info->mData);
46738b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            }
46745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mData->meta()->setInt64("timeUs", timeUs);
4675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
46765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4677d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatDrainThisBuffer);
4678609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            notify->setInt32("buffer-id", info->mBufferID);
46792d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            notify->setBuffer("buffer", info->mData);
46805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("flags", flags);
4681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4682609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            reply->setInt32("buffer-id", info->mBufferID);
4683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
46845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setMessage("reply", reply);
4685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
46865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->post();
46875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
46885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
4689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (flags & OMX_BUFFERFLAG_EOS) {
46915778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
46925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                sp<AMessage> notify = mCodec->mNotify->dup();
4694d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar                notify->setInt32("what", CodecBase::kWhatEOS);
4695dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                notify->setInt32("err", mCodec->mInputEOSResult);
4696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->post();
4697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexOutput] = true;
4699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
4706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
4708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
4709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4716f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
4717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
4718609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
4719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
4720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
4721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
4722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM);
4723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4724577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    android_native_rect_t crop;
4725577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    if (msg->findRect("crop",
4726577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            &crop.left, &crop.top, &crop.right, &crop.bottom)) {
4727577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar        CHECK_EQ(0, native_window_set_crop(
4728577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->mNativeWindow.get(), &crop));
4729577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    }
4730577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
4731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t render;
4732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mNativeWindow != NULL
47336aade6058521b0dbd35a9a4620f4d04f02f90444Marco Nelissen            && msg->findInt32("render", &render) && render != 0
473479ee2399b67c7a11042c5904dc1309712a76f8cbJianzheng Zhou            && info->mData != NULL && info->mData->size() != 0) {
47356fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        ATRACE_NAME("render");
4736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The client wants this buffer to be rendered.
4737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4738fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        int64_t timestampNs = 0;
4739fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        if (!msg->findInt64("timestampNs", &timestampNs)) {
4740fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // TODO: it seems like we should use the timestamp
4741fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // in the (media)buffer as it potentially came from
4742fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // an input surface, but we did not propagate it prior to
4743fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // API 20.  Perhaps check for target SDK version.
4744fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#if 0
4745fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            if (info->mData->meta()->findInt64("timeUs", &timestampNs)) {
474647aea1f7c58f5302b16822f9e7e1763f2af04ef5Lajos Molnar                ALOGV("using buffer PTS of %" PRId64, timestampNs);
4747fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar                timestampNs *= 1000;
4748fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            }
4749fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#endif
4750fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
4751fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
47525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err;
4753fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        err = native_window_set_buffers_timestamp(mCodec->mNativeWindow.get(), timestampNs);
4754fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        if (err != OK) {
4755fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            ALOGW("failed to set buffer timestamp: %d", err);
4756fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
4757fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
47585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if ((err = mCodec->mNativeWindow->queueBuffer(
4759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNativeWindow.get(),
47601e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                    info->mGraphicBuffer.get(), -1)) == OK) {
4761cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
4762cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        } else {
4763251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
4764cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
4765cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        }
4766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
47676fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        if (mCodec->mNativeWindow != NULL &&
47686fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar            (info->mData == NULL || info->mData->size() != 0)) {
47696fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar            ATRACE_NAME("frame-drop");
47706fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        }
4771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_US;
4772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
4775f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
4780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // We cannot resubmit the buffer we just rendered, dequeue
4783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // the spare instead.
4784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info = mCodec->dequeueBufferFromNativeWindow();
4786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (!mCodec->mPortEOS[kPortIndexOutput]) {
4793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // We cannot resubmit the buffer we just rendered, dequeue
4795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // the spare instead.
4796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info = mCodec->dequeueBufferFromNativeWindow();
4798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
4799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4800c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                if (info != NULL) {
4801609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                    ALOGV("[%s] calling fillBuffer %u",
4802c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                         mCodec->mComponentName.c_str(), info->mBufferID);
4803349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4804c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
4805c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                             (status_t)OK);
4806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4807c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4808c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                }
4809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
4816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
4818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
4819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4826f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::UninitializedState::UninitializedState(ACodec *codec)
4827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4830c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::UninitializedState::stateEntered() {
4831c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("Now uninitialized");
4832ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4833ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (mDeathNotifier != NULL) {
4834f888020c6e2735624f2b2a30e72aca24e17b8b4dMarco Nelissen        IInterface::asBinder(mCodec->mOMX)->unlinkToDeath(mDeathNotifier);
4835ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
4836ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
4837ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4838ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNativeWindow.clear();
4839ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    mCodec->mNode = 0;
4840ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mOMX.clear();
4841ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mQuirks = 0;
4842ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mFlags = 0;
4843308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    mCodec->mUseMetadataOnEncoderOutput = 0;
4844ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mComponentName.clear();
4845c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4846c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4847f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
4848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4850f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatSetup:
4852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onSetup(msg);
4854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
48595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case ACodec::kWhatAllocateComponent:
48605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
48615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            onAllocateComponent(msg);
48625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            handled = true;
48635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
48645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
48655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatShutdown:
4867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4868c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
4869c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
4870c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
487154b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            ALOGW_IF(keepComponentAllocated,
487254b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar                     "cannot keep component allocated on shutdown in Uninitialized state");
4873c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4875d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
4876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
4877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4879c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
4880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatFlush:
4883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4885d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
4886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
4887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4889c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
4890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
489230358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        case ACodec::kWhatReleaseCodecInstance:
489330358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        {
489430358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            // nothing to do, as we have already signaled shutdown
489530358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            handled = true;
489630358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            break;
489730358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        }
489830358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar
4899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
4901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4906f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::UninitializedState::onSetup(
4907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4908c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (onAllocateComponent(msg)
4909c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            && mCodec->mLoadedState->onConfigureComponent(msg)) {
4910c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mLoadedState->onStart();
4911c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
49125778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
49135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4914c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
49155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onAllocateComponent");
49165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4917ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    CHECK(mCodec->mNode == 0);
49185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMXClient client;
492048a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung    if (client.connect() != OK) {
492148a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung        mCodec->signalError(OMX_ErrorUndefined, NO_INIT);
492248a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung        return false;
492348a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung    }
4924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<IOMX> omx = client.interface();
4926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
49271d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec);
4928ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4929ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mDeathNotifier = new DeathNotifier(notify);
4930f888020c6e2735624f2b2a30e72aca24e17b8b4dMarco Nelissen    if (IInterface::asBinder(omx)->linkToDeath(mDeathNotifier) != OK) {
4931ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // This was a local binder, if it dies so do we, we won't care
4932ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // about any notifications in the afterlife.
4933ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
4934ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
4935ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4936e671207115fac3914134c61b336d5fa0242c68caAndreas Huber    Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs;
49375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    AString mime;
4939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
49405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString componentName;
4941d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint32_t quirks = 0;
49427791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen    int32_t encoder = false;
49435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findString("componentName", &componentName)) {
4944e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        ssize_t index = matchingCodecs.add();
4945e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        OMXCodec::CodecNameAndQuirks *entry = &matchingCodecs.editItemAt(index);
4946e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        entry->mName = String8(componentName.c_str());
4947afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
4948e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        if (!OMXCodec::findCodecQuirks(
4949e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                    componentName.c_str(), &entry->mQuirks)) {
4950e671207115fac3914134c61b336d5fa0242c68caAndreas Huber            entry->mQuirks = 0;
4951afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
49525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
49535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(msg->findString("mime", &mime));
49545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
49555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("encoder", &encoder)) {
49565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder = false;
49575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
49585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
49595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMXCodec::findMatchingCodecs(
49605778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mime.c_str(),
49615778822d86b0337407514b9372562b86edfa91cdAndreas Huber                encoder, // createEncoder
49625778822d86b0337407514b9372562b86edfa91cdAndreas Huber                NULL,  // matchComponentName
49635778822d86b0337407514b9372562b86edfa91cdAndreas Huber                0,     // flags
4964e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                &matchingCodecs);
49655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
49661065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
49671065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    sp<CodecObserver> observer = new CodecObserver;
4968ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    IOMX::node_id node = 0;
49691065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
49709f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu    status_t err = OMX_ErrorComponentNotFound;
49711065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
49721065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            ++matchIndex) {
4973e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        componentName = matchingCodecs.itemAt(matchIndex).mName.string();
4974e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        quirks = matchingCodecs.itemAt(matchIndex).mQuirks;
4975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4976da153975581fb3161a30452348a5b26ee72d9255Elliott Hughes        pid_t tid = gettid();
4977078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        int prevPriority = androidGetThreadPriority(tid);
4978078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
49799f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu        err = omx->allocateNode(componentName.c_str(), observer, &node);
4980078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, prevPriority);
4981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
49821065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        if (err == OK) {
49831065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            break;
49847a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He        } else {
49857a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He            ALOGW("Allocating component '%s' failed, try next one.", componentName.c_str());
49861065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
49871065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
4988ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        node = 0;
49891065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    }
49901065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
4991ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    if (node == 0) {
49925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!mime.empty()) {
49939f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu            ALOGE("Unable to instantiate a %scoder for type '%s' with err %#x.",
49949f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu                    encoder ? "en" : "de", mime.c_str(), err);
49955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
49969f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu            ALOGE("Unable to instantiate codec '%s' with err %#x.", componentName.c_str(), err);
49975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
4998c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
499952e88b2986536e83a7a6da63461556b8734a85f3Ronghua Wu        mCodec->signalError((OMX_ERRORTYPE)err, makeNoSideEffectStatus(err));
5000c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
5001c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
5002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
50031d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    notify = new AMessage(kWhatOMXMessage, mCodec);
5004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    observer->setNotificationMessage(notify);
5005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mComponentName = componentName;
5007ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    mCodec->mFlags = 0;
5008ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
5009ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (componentName.endsWith(".secure")) {
5010ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        mCodec->mFlags |= kFlagIsSecure;
50111713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        mCodec->mFlags |= kFlagIsGrallocUsageProtected;
50120167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
5013ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
5014ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
5015afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mCodec->mQuirks = quirks;
5016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mOMX = omx;
5017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mNode = node;
5018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
50195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
50205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
5021d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatComponentAllocated);
50225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setString("componentName", mCodec->mComponentName.c_str());
50235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
50245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5025c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5026c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mCodec->changeState(mCodec->mLoadedState);
5027c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5028c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
50295778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
50305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5031c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
5032c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5033c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas HuberACodec::LoadedState::LoadedState(ACodec *codec)
5034c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    : BaseState(codec) {
5035c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
5036c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5037c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::stateEntered() {
5038c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
5039c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5040f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mPortEOS[kPortIndexInput] =
5041f6f38287b97ec69b169387add6458f859b770e65Andreas Huber        mCodec->mPortEOS[kPortIndexOutput] = false;
5042f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
5043f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mInputEOSResult = OK;
5044f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
5045054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mDequeueCounter = 0;
5046054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mMetaDataBuffersToSubmit = 0;
5047a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    mCodec->mRepeatFrameDelayUs = -1ll;
5048e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mInputFormat.clear();
5049e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mOutputFormat.clear();
50504e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    mCodec->mBaseOutputFormat.clear();
5051054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5052c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (mCodec->mShutdownInProgress) {
5053c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
5054c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5055c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mShutdownInProgress = false;
5056c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mKeepComponentAllocated = false;
5057c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5058c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        onShutdown(keepComponentAllocated);
5059c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
506054b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    mCodec->mExplicitShutdown = false;
5061f393c33e65ae51a7cf168b4e15771b152f996b32Wei Jia
5062f393c33e65ae51a7cf168b4e15771b152f996b32Wei Jia    mCodec->processDeferredMessages();
5063c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
5064c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5065c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
5066c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (!keepComponentAllocated) {
5067c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK);
5068c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5069c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->changeState(mCodec->mUninitializedState);
5070c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
5071c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
507254b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    if (mCodec->mExplicitShutdown) {
507354b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        sp<AMessage> notify = mCodec->mNotify->dup();
5074d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
507554b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        notify->post();
507654b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        mCodec->mExplicitShutdown = false;
507754b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    }
5078c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
5079c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5080c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
5081c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool handled = false;
5082c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5083c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    switch (msg->what()) {
5084c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatConfigureComponent:
5085c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
5086c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onConfigureComponent(msg);
5087c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
5088c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
5089c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
5090c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
50917cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
50927cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
50937cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            onCreateInputSurface(msg);
50947cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
50957cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
50967cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
50977cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
5098c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatStart:
5099c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
5100c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onStart();
5101c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
5102c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
5103c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
5104c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5105c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatShutdown:
5106c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
5107c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
5108c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
5109c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
5110c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
511154b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
5112c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onShutdown(keepComponentAllocated);
5113c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5114c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
5115c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
5116c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
5117c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5118c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatFlush:
5119c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
5120c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
5121d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
5122c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->post();
5123c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5124c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
5125c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
5126c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
5127c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5128c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        default:
5129c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            return BaseState::onMessageReceived(msg);
5130c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
5131c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5132c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return handled;
5133c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
5134c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5135c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onConfigureComponent(
51365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg) {
51375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onConfigureComponent");
51385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5139ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    CHECK(mCodec->mNode != 0);
51405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
51415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString mime;
51425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findString("mime", &mime));
51435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
51445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mCodec->configureCodec(mime.c_str(), msg);
51455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
51465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
5147c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        ALOGE("[%s] configureCodec returning error %d",
5148c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber              mCodec->mComponentName.c_str(), err);
5149c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber
5150251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5151c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
51525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
51545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
51555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
5156d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatComponentConfigured);
5157e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("input-format", mCodec->mInputFormat);
5158e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("output-format", mCodec->mOutputFormat);
51595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
51605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5161c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5162c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
51635778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
51645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
51657cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::LoadedState::onCreateInputSurface(
5166ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        const sp<AMessage> & /* msg */) {
51677cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    ALOGV("onCreateInputSurface");
51687cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
51697cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<AMessage> notify = mCodec->mNotify->dup();
5170d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatInputSurfaceCreated);
51717cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
51727cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<IGraphicBufferProducer> bufferProducer;
51737cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    status_t err;
51747cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
51757cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    err = mCodec->mOMX->createInputSurface(mCodec->mNode, kPortIndexInput,
51767cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            &bufferProducer);
5177a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
5178a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    if (err == OK && mCodec->mRepeatFrameDelayUs > 0ll) {
5179a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        err = mCodec->mOMX->setInternalOption(
5180a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                mCodec->mNode,
5181a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                kPortIndexInput,
5182a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY,
5183a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                &mCodec->mRepeatFrameDelayUs,
5184a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                sizeof(mCodec->mRepeatFrameDelayUs));
5185a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
5186a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (err != OK) {
5187a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            ALOGE("[%s] Unable to configure option to repeat previous "
5188a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  "frames (err %d)",
5189a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  mCodec->mComponentName.c_str(),
5190a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  err);
5191a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
5192a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
5193a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
51942c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    if (err == OK && mCodec->mMaxPtsGapUs > 0ll) {
519594ee4b708acfa941581160b267afb79192b1d816Chong Zhang        err = mCodec->mOMX->setInternalOption(
519694ee4b708acfa941581160b267afb79192b1d816Chong Zhang                mCodec->mNode,
519794ee4b708acfa941581160b267afb79192b1d816Chong Zhang                kPortIndexInput,
519894ee4b708acfa941581160b267afb79192b1d816Chong Zhang                IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP,
519994ee4b708acfa941581160b267afb79192b1d816Chong Zhang                &mCodec->mMaxPtsGapUs,
520094ee4b708acfa941581160b267afb79192b1d816Chong Zhang                sizeof(mCodec->mMaxPtsGapUs));
520194ee4b708acfa941581160b267afb79192b1d816Chong Zhang
520294ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (err != OK) {
520394ee4b708acfa941581160b267afb79192b1d816Chong Zhang            ALOGE("[%s] Unable to configure max timestamp gap (err %d)",
520472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    mCodec->mComponentName.c_str(),
520572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    err);
52062c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
52072c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
52082c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
520937b2b389139ed638831e49708c947863eef631efRonghua Wu    if (err == OK && mCodec->mMaxFps > 0) {
521037b2b389139ed638831e49708c947863eef631efRonghua Wu        err = mCodec->mOMX->setInternalOption(
521137b2b389139ed638831e49708c947863eef631efRonghua Wu                mCodec->mNode,
521237b2b389139ed638831e49708c947863eef631efRonghua Wu                kPortIndexInput,
521337b2b389139ed638831e49708c947863eef631efRonghua Wu                IOMX::INTERNAL_OPTION_MAX_FPS,
521437b2b389139ed638831e49708c947863eef631efRonghua Wu                &mCodec->mMaxFps,
521537b2b389139ed638831e49708c947863eef631efRonghua Wu                sizeof(mCodec->mMaxFps));
521637b2b389139ed638831e49708c947863eef631efRonghua Wu
521737b2b389139ed638831e49708c947863eef631efRonghua Wu        if (err != OK) {
521837b2b389139ed638831e49708c947863eef631efRonghua Wu            ALOGE("[%s] Unable to configure max fps (err %d)",
521937b2b389139ed638831e49708c947863eef631efRonghua Wu                    mCodec->mComponentName.c_str(),
522037b2b389139ed638831e49708c947863eef631efRonghua Wu                    err);
522137b2b389139ed638831e49708c947863eef631efRonghua Wu        }
522237b2b389139ed638831e49708c947863eef631efRonghua Wu    }
522337b2b389139ed638831e49708c947863eef631efRonghua Wu
52242c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    if (err == OK && mCodec->mTimePerCaptureUs > 0ll
52252c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            && mCodec->mTimePerFrameUs > 0ll) {
52262c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        int64_t timeLapse[2];
52272c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[0] = mCodec->mTimePerFrameUs;
52282c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[1] = mCodec->mTimePerCaptureUs;
52292c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        err = mCodec->mOMX->setInternalOption(
52302c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                mCodec->mNode,
52312c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                kPortIndexInput,
52322c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                IOMX::INTERNAL_OPTION_TIME_LAPSE,
52332c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                &timeLapse[0],
52342c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                sizeof(timeLapse));
52352c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
52362c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (err != OK) {
52372c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            ALOGE("[%s] Unable to configure time lapse (err %d)",
52382c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    mCodec->mComponentName.c_str(),
52392c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    err);
52402c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
52412c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
524272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
524372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (err == OK && mCodec->mCreateInputBuffersSuspended) {
524472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        bool suspend = true;
524572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        err = mCodec->mOMX->setInternalOption(
524672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                mCodec->mNode,
524772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                kPortIndexInput,
524872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                IOMX::INTERNAL_OPTION_SUSPEND,
524972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                &suspend,
525072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                sizeof(suspend));
525172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
525272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
525372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("[%s] Unable to configure option to suspend (err %d)",
525494ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  mCodec->mComponentName.c_str(),
525594ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  err);
525694ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
525794ee4b708acfa941581160b267afb79192b1d816Chong Zhang    }
525894ee4b708acfa941581160b267afb79192b1d816Chong Zhang
52597cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err == OK) {
52607cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setObject("input-surface",
52617cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                new BufferProducerWrapper(bufferProducer));
52627cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else {
52637cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // Can't use mCodec->signalError() here -- MediaCodec won't forward
52647cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // the error through because it's in the "configured" state.  We
52657cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // send a kWhatInputSurfaceCreated with an error value instead.
52667cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGE("[%s] onCreateInputSurface returning error %d",
52677cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                mCodec->mComponentName.c_str(), err);
52687cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setInt32("err", err);
52697cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
52707cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->post();
52717cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
52727cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
5273c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onStart() {
52745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onStart");
52755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
52765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ(mCodec->mOMX->sendCommand(
52775778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
5278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
5279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->changeState(mCodec->mLoadedToIdleState);
5281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5285f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
5286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5289f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::LoadedToIdleState::stateEntered() {
52903856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
5291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5292cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    status_t err;
5293cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    if ((err = allocateBuffers()) != OK) {
529429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to allocate buffers after transitioning to IDLE state "
5295cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             "(error 0x%08x)",
5296cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             err);
5297cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
5298251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
529991bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber
530091bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber        mCodec->changeState(mCodec->mLoadedState);
5301cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    }
5302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5304f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::LoadedToIdleState::allocateBuffers() {
5305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
5306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
5308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
5309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mCodec->allocateBuffersOnPort(kPortIndexOutput);
5312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5314f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
5315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
531672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
5317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
5320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
53236507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
53246507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
53256507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
53266507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
53276507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
53286507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
53296463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatResume:
53306463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
53316463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We'll be active soon enough.
53326463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
53336463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
53346463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
53356463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatFlush:
53366463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
53376463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We haven't even started yet, so we're flushed alright...
53386463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            sp<AMessage> notify = mCodec->mNotify->dup();
5339d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
53406463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->post();
53416463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
53426463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
53436463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
5344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
5346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5349f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onOMXEvent(
5350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
5355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
5356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
5358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting),
5359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
5360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mIdleToExecutingState);
5362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5373f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
5374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5377f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToExecutingState::stateEntered() {
53783856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
5379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5381f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
5382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
538372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
5384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
5387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5390d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatResume:
5391d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
5392d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We'll be active soon enough.
5393d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
5394d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
5395d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
5396d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatFlush:
5397d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
5398d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We haven't even started yet, so we're flushed alright...
5399d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
5400d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
5401d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->post();
5402d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
5403d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
5404d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
5405d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
54066507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
54076507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
54086507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
54096507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
54106507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
54116507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
5412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
5414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5417f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onOMXEvent(
5418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
5423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateExecuting);
5424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mExecutingState->resume();
5426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingState);
5427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5438f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingState::ExecutingState(ACodec *codec)
5439349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    : BaseState(codec),
5440349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber      mActive(false) {
5441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5443f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
5444ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
5445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
5446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5448054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputMetaBuffers() {
5449054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // submit as many buffers as there are input buffers with the codec
5450054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // in case we are in port reconfiguring
5451054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
5452054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
5453054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5454054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) {
5455054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            if (mCodec->submitOutputMetaDataBuffer() != OK)
5456054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                break;
5457054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
5458054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
54594dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
54604dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
54614dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
5462054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
5463054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5464054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitRegularOutputBuffers() {
5465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
5466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
5467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mCodec->mNativeWindow != NULL) {
5469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(info->mStatus == BufferInfo::OWNED_BY_US
5470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
5471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
5473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                continue;
5474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
5476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
5477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5479ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        ALOGV("[%s] calling fillBuffer %u",
5480349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str(), info->mBufferID);
5481349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
5483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
5484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
5486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5489054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputBuffers() {
5490c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar    submitRegularOutputBuffers();
5491054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mCodec->mStoreMetaDataInOutputBuffers) {
5492054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        submitOutputMetaBuffers();
5493054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
5494054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
5495054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5496f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::resume() {
5497349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    if (mActive) {
54983856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] We're already active, no need to resume.",
5499349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str());
5500349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5501349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        return;
5502349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    }
5503349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    submitOutputBuffers();
5505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
55063cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    // Post all available input buffers
5507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_GT(mCodec->mBuffers[kPortIndexInput].size(), 0u);
55083cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); i++) {
55093cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
55103cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_US) {
55113cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar            postFillThisBuffer(info);
55123cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        }
55133cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    }
5514349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5515349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    mActive = true;
5516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5518f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::stateEntered() {
55193856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
5520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->processDeferredMessages();
5522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5524f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
5525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5530c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
5531c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
5532c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
5533c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5534c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mShutdownInProgress = true;
553554b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
5536c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mKeepComponentAllocated = keepComponentAllocated;
5537c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5538349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
5539349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
5541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
5542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
5543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingToIdleState);
5545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
55527a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong            ALOGV("[%s] ExecutingState flushing now "
5553ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                 "(codec owns %zu/%zu input, %zu/%zu output).",
5554d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mComponentName.c_str(),
5555d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
5556d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexInput].size(),
5557d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
5558d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexOutput].size());
5559d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
5560349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
5561349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
5563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandFlush, OMX_ALL),
5564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
5565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mFlushingState);
5567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatResume:
5572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            resume();
5574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5579496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
5580496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
5581496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            status_t err = mCodec->requestIDRFrame();
5582496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            if (err != OK) {
5583496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                ALOGW("Requesting an IDR frame failed.");
5584496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            }
5585496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5586496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            handled = true;
5587496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
5588496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
5589496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5590a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
5591a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
5592a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
5593a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
5594a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5595a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = mCodec->setParameters(params);
5596a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5597a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> reply;
5598a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            if (msg->findMessage("reply", &reply)) {
5599a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->setInt32("err", err);
5600a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->post();
5601a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            }
5602a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5603a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            handled = true;
5604a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
5605a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
5606a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
56077cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
56087cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
56096507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
56107cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
56117cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
56127cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
56137cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
56144dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
56154dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        case kWhatSubmitOutputMetaDataBufferIfEOS:
56164dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        {
56174dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            if (mCodec->mPortEOS[kPortIndexInput] &&
56184dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    !mCodec->mPortEOS[kPortIndexOutput]) {
56194dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                status_t err = mCodec->submitOutputMetaDataBuffer();
56204dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                if (err == OK) {
56214dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
56224dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                }
56234dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            }
56244dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            return true;
56254dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        }
56264dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
5627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5635a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t ACodec::setParameters(const sp<AMessage> &params) {
5636a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    int32_t videoBitrate;
5637530fdbdc1b5491f3fbf172752834d1515701e142Lajos Molnar    if (params->findInt32("video-bitrate", &videoBitrate)) {
5638a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        OMX_VIDEO_CONFIG_BITRATETYPE configParams;
5639a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        InitOMXParams(&configParams);
5640a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nPortIndex = kPortIndexOutput;
5641a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nEncodeBitrate = videoBitrate;
5642a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5643a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        status_t err = mOMX->setConfig(
5644a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                mNode,
5645a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                OMX_IndexConfigVideoBitrate,
5646a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                &configParams,
5647a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                sizeof(configParams));
5648a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5649a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        if (err != OK) {
5650a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
5651a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                   videoBitrate, err);
5652a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5653a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            return err;
5654a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
5655a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    }
5656a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
565772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    int64_t skipFramesBeforeUs;
565872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (params->findInt64("skip-frames-before", &skipFramesBeforeUs)) {
565972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        status_t err =
566072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mOMX->setInternalOption(
566172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     mNode,
566272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     kPortIndexInput,
566372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     IOMX::INTERNAL_OPTION_START_TIME,
566472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     &skipFramesBeforeUs,
566572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     sizeof(skipFramesBeforeUs));
566672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
566772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
566872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("Failed to set parameter 'skip-frames-before' (err %d)", err);
566972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            return err;
567072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
567172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
567272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
5673e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    int32_t dropInputFrames;
5674e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    if (params->findInt32("drop-input-frames", &dropInputFrames)) {
5675e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        bool suspend = dropInputFrames != 0;
5676e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
5677b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err =
5678b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            mOMX->setInternalOption(
5679e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     mNode,
5680e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     kPortIndexInput,
5681e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     IOMX::INTERNAL_OPTION_SUSPEND,
5682e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     &suspend,
5683b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber                     sizeof(suspend));
5684b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
5685b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
5686b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err);
5687b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
5688b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
5689b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    }
5690b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
5691b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    int32_t dummy;
5692b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    if (params->findInt32("request-sync", &dummy)) {
5693b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err = requestIDRFrame();
5694b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
5695b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
5696b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Requesting a sync frame failed w/ err %d", err);
5697b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
5698b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
5699e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    }
5700e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
57018db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    float rate;
57028db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    if (params->findFloat("operating-rate", &rate) && rate > 0) {
57038db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        status_t err = setOperatingRate(rate, mIsVideo);
57048db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        if (err != OK) {
57058db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu            ALOGE("Failed to set parameter 'operating-rate' (err %d)", err);
57068db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu            return err;
57078db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        }
57088db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    }
57098db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu
5710a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return OK;
5711a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
5712a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
57136507d14c6d10f93d390de62b9eed267f9b544985Andy McFaddenvoid ACodec::onSignalEndOfInputStream() {
57146507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    sp<AMessage> notify = mNotify->dup();
5715d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatSignaledInputEOS);
57166507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
57176507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    status_t err = mOMX->signalEndOfInputStream(mNode);
57186507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    if (err != OK) {
57196507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        notify->setInt32("err", err);
57206507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    }
57216507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->post();
57226507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden}
57236507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
5724f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onOMXEvent(
5725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventPortSettingsChanged:
5728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
5730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
573131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
5732054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mCodec->mMetaDataBuffersToSubmit = 0;
5733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
5734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
5735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_CommandPortDisable, kPortIndexOutput),
5736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
5737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5738349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                mCodec->freeOutputBuffersNotOwnedByComponent();
5739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
574131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            } else if (data2 == OMX_IndexConfigCommonOutputCrop) {
574231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
5743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
5744ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08x",
5745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->mComponentName.c_str(), data2);
5746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventBufferFlag:
5752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5763f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
5764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ACodec *codec)
5765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5768f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
5769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
5770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput) {
5771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return FREE_BUFFERS;
5772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
5775f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
5777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5779f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onMessageReceived(
5780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
5781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5786349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case kWhatResume:
5787e6eea3a6b6e0cf92287ec1ceb8350f201d17e1acPer Persson        case kWhatSetParameters:
5788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5789349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            if (msg->what() == kWhatResume) {
57903856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
5791349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            }
5792349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
5794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5806f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::OutputPortSettingsChangedState::stateEntered() {
58073856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now handling output port settings change",
5808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mCodec->mComponentName.c_str());
5809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5811f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onOMXEvent(
5812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
5817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
5818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
58193856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now disabled.",
5820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
5821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mCodec->mBuffers[kPortIndexOutput].isEmpty());
5823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mDealer[kPortIndexOutput].clear();
5824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
5826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput),
5827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
5828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5829cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                status_t err;
5830cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                if ((err = mCodec->allocateBuffersOnPort(
5831cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                                kPortIndexOutput)) != OK) {
583229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("Failed to allocate output port buffers after "
5833cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         "port reconfiguration (error 0x%08x)",
5834cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         err);
5835cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
5836251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5837d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
5838755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // This is technically not correct, but appears to be
5839755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the only way to free the component instance.
5840755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // Controlled transitioning from excecuting->idle
5841755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // and idle->loaded seem impossible probably because
5842755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the output port never finishes re-enabling.
5843755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mShutdownInProgress = true;
5844755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mKeepComponentAllocated = false;
5845755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->changeState(mCodec->mLoadedState);
5846cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                }
5847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
5849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
5850f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
5851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
585231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
585331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
58543856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now reenabled.",
5855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
5856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5857349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                if (mCodec->mExecutingState->active()) {
5858349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    mCodec->mExecutingState->submitOutputBuffers();
5859349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                }
5860349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mExecutingState);
5862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
5864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
5867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
5871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5876f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
58775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : BaseState(codec),
58785778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mComponentNowIdle(false) {
5879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5881f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
5882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
5888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
5889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
5890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
5896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5909f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::stateEntered() {
59103856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
591131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
59125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mComponentNowIdle = false;
591331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mCodec->mSentFormat = false;
5914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5916f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onOMXEvent(
5917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
5922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
5923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
59245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mComponentNowIdle = true;
59255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            changeStateIfWeOwnAllBuffers();
5927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5931349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
5932349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventBufferFlag:
5933349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
5934349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We're shutting down and don't care about this anymore.
5935349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
5936349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
5937349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
59420af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
5943f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
59445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
5945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->sendCommand(
5946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded),
5947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
5948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexInput), (status_t)OK);
5950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexOutput), (status_t)OK);
5951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
59520167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown)
59530167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && mCodec->mNativeWindow != NULL) {
5954bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // We push enough 1x1 blank buffers to ensure that one of
5955bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // them has made it to the display.  This allows the OMX
5956bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // component teardown to zero out any protected buffers
5957bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // without the risk of scanning out one of those buffers.
5958bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            mCodec->pushBlankBuffersToNativeWindow();
5959bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
5960bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
5961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mIdleToLoadedState);
5962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5965f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onInputBufferFilled(
5966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
5967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
5968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
5970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5972f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onOutputBufferDrained(
5973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
5974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
5975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
5977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5981f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
5982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5985f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
5986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
5992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
6000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
6001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
6002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
6007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
6011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6013f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToLoadedState::stateEntered() {
60143856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
6015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6017f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onOMXEvent(
6018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
6020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
6021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
6023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateLoaded);
6024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6025c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->changeState(mCodec->mLoadedState);
6026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
6032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
6036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6037f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::FlushingState::FlushingState(ACodec *codec)
6038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
6039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6041f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::stateEntered() {
60423856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
6043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
6045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6047f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
6048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
6049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
6051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
6052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
6054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
6058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing this right now.
6060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
6066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
6070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6072f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onOMXEvent(
6073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6074ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGV("[%s] FlushingState onOMXEvent(%u,%d)",
6075ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar            mCodec->mComponentName.c_str(), event, (OMX_S32)data1);
6076d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
6077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
6078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
6079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandFlush);
6081f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
6083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(!mFlushComplete[data2]);
6084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mFlushComplete[data2] = true;
6085e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber
6086e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                if (mFlushComplete[kPortIndexInput]
6087e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                        && mFlushComplete[kPortIndexOutput]) {
6088e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                    changeStateIfWeOwnAllBuffers();
6089e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                }
6090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
6091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, OMX_ALL);
6092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexInput]);
6093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexOutput]);
6094f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6095f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                changeStateIfWeOwnAllBuffers();
6096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
6097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6101349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
6102349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
61031d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec);
6104349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("type", omx_message::EVENT);
6105609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            msg->setInt32("node", mCodec->mNode);
6106349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("event", event);
6107349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data1", data1);
6108349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data2", data2);
6109349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
61103856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
6111349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                 mCodec->mComponentName.c_str());
6112349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6113349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mCodec->deferMessage(msg);
6114349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6115349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
6116349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
6117349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
6120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
6123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6125f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
6126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
6127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
6129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6131f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
6132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
6133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
6135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6137f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
6138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mFlushComplete[kPortIndexInput]
6139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mFlushComplete[kPortIndexOutput]
6140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mCodec->allYourBuffersAreBelongToUs()) {
61417e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // We now own all buffers except possibly those still queued with
61427e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // the native window for rendering. Let's get those back as well.
61437e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
61447e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
6145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
6146d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatFlushCompleted);
6147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->post();
6148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->mPortEOS[kPortIndexInput] =
6150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mPortEOS[kPortIndexOutput] = false;
6151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6152dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber        mCodec->mInputEOSResult = OK;
6153dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
6154f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        if (mCodec->mSkipCutBuffer != NULL) {
6155f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen            mCodec->mSkipCutBuffer->clear();
6156f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        }
6157f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen
6158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mExecutingState);
6159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
6163