ACodec.cpp revision dd248abd2c3e5e82b0049d40c7e9fb741fd4540c
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>
44d291c222357303b9611cab89d0c3b047584ef377Chong Zhang#include <media/stagefright/PersistentSurface.h>
45b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar#include <media/stagefright/SurfaceUtils.h>
463a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber#include <media/hardware/HardwareAPI.h>
473a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
4897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu#include <OMX_AudioExt.h>
494154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev#include <OMX_VideoExt.h>
50f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <OMX_Component.h>
5197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu#include <OMX_IndexExt.h>
52f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
53496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#include "include/avc_utils.h"
54496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
55f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android {
56f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
57251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// OMX errors are directly mapped into status_t range if
58251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// there is no corresponding MediaError status code.
59251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Use the statusFromOMXError(int32_t omxError) function.
60251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung//
61251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Currently this is a direct map.
62251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// See frameworks/native/include/media/openmax/OMX_Core.h
63251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung//
64251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Vendor OMX errors     from 0x90000000 - 0x9000FFFF
65251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Extension OMX errors  from 0x8F000000 - 0x90000000
66251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Standard OMX errors   from 0x80001000 - 0x80001024 (0x80001024 current)
67251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung//
68251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
69251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// returns true if err is a recognized OMX error code.
70251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// as OMX error is OMX_S32, this is an int32_t type
71251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hungstatic inline bool isOMXError(int32_t err) {
72251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    return (ERROR_CODEC_MIN <= err && err <= ERROR_CODEC_MAX);
73251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung}
74251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
75251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// converts an OMX error to a status_t
76251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hungstatic inline status_t statusFromOMXError(int32_t omxError) {
77251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    switch (omxError) {
78251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case OMX_ErrorInvalidComponentName:
79251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case OMX_ErrorComponentNotFound:
80251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return NAME_NOT_FOUND; // can trigger illegal argument error for provided names.
81251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    default:
82251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return isOMXError(omxError) ? omxError : 0; // no translation required
83251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
84251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung}
85251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
86251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// checks and converts status_t to a non-side-effect status_t
87251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hungstatic inline status_t makeNoSideEffectStatus(status_t err) {
88251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    switch (err) {
89251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // the following errors have side effects and may come
90251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // from other code modules. Remap for safety reasons.
91251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case INVALID_OPERATION:
92251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case DEAD_OBJECT:
93251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return UNKNOWN_ERROR;
94251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    default:
95251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return err;
96251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
97251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung}
98251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
99f933441648ef6a71dee783d733aac17b9508b452Andreas Hubertemplate<class T>
100f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic void InitOMXParams(T *params) {
101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nSize = sizeof(T);
102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nVersionMajor = 1;
103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nVersionMinor = 0;
104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nRevision = 0;
105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nStep = 0;
106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
108f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct CodecObserver : public BnOMXObserver {
109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CodecObserver() {}
110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void setNotificationMessage(const sp<AMessage> &msg) {
112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mNotify = msg;
113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // from IOMXObserver
116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onMessage(const omx_message &omx_msg) {
117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> msg = mNotify->dup();
118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->setInt32("type", omx_msg.type);
120609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        msg->setInt32("node", omx_msg.node);
121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        switch (omx_msg.type) {
123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::EVENT:
124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("event", omx_msg.u.event_data.event);
126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("data1", omx_msg.u.event_data.data1);
127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("data2", omx_msg.u.event_data.data2);
128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::EMPTY_BUFFER_DONE:
132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
133609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                msg->setInt32("buffer", omx_msg.u.buffer_data.buffer);
134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::FILL_BUFFER_DONE:
138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
139609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                msg->setInt32(
140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "buffer", omx_msg.u.extended_buffer_data.buffer);
141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "range_offset",
143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.range_offset);
144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "range_length",
146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.range_length);
147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "flags",
149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.flags);
150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt64(
151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "timestamp",
152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.timestamp);
153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            default:
157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                TRESPASS();
158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->post();
162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
164f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual ~CodecObserver() {}
166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
167f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> mNotify;
169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(CodecObserver);
171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
175f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::BaseState : public AState {
176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState(ACodec *codec, const sp<AState> &parentState = NULL);
177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
178f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    enum PortMode {
180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        KEEP_BUFFERS,
181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        RESUBMIT_BUFFERS,
182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        FREE_BUFFERS,
183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ACodec *mCodec;
186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void postFillThisBuffer(BufferInfo *info);
197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
198f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXMessage(const sp<AMessage> &msg);
200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXEmptyBufferDone(IOMX::buffer_id bufferID);
202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXFillBufferDone(
204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID,
205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            size_t rangeOffset, size_t rangeLength,
206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            OMX_U32 flags,
207784e24e386b088c05d653ab482f2e95cb53e3d01Andy Hung            int64_t timeUs);
208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void getMoreInputDataIfPossible();
210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(BaseState);
212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
216ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberstruct ACodec::DeathNotifier : public IBinder::DeathRecipient {
217ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    DeathNotifier(const sp<AMessage> &notify)
218ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        : mNotify(notify) {
219ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
220ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
221ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual void binderDied(const wp<IBinder> &) {
222ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mNotify->post();
223ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
224ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
225ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprotected:
226ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual ~DeathNotifier() {}
227ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
228ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprivate:
229ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> mNotify;
230ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
231ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(DeathNotifier);
232ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber};
233ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
234f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::UninitializedState : public ACodec::BaseState {
235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    UninitializedState(ACodec *codec);
236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
237f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
239c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
241f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void onSetup(const sp<AMessage> &msg);
243c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onAllocateComponent(const sp<AMessage> &msg);
244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
245ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<DeathNotifier> mDeathNotifier;
246ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(UninitializedState);
248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
252c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberstruct ACodec::LoadedState : public ACodec::BaseState {
253c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    LoadedState(ACodec *codec);
254c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
255c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprotected:
256c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
257c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
258c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
259c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprivate:
260c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    friend struct ACodec::UninitializedState;
261c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
262c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onConfigureComponent(const sp<AMessage> &msg);
2637cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    void onCreateInputSurface(const sp<AMessage> &msg);
264d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    void onUsePersistentInputSurface(const sp<AMessage> &msg);
265c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onStart();
266c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onShutdown(bool keepComponentAllocated);
267c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
268d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    status_t setupInputSurface();
269d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
270c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedState);
271c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber};
272c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
273c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
274c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
275f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::LoadedToIdleState : public ACodec::BaseState {
276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    LoadedToIdleState(ACodec *codec);
277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
278f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
283f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t allocateBuffers();
285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedToIdleState);
287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
291f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToExecutingState : public ACodec::BaseState {
292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToExecutingState(ACodec *codec);
293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
294f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
299f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToExecutingState);
301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
305f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingState : public ACodec::BaseState {
306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingState(ACodec *codec);
307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
308054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitRegularOutputBuffers();
309054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitOutputMetaBuffers();
310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void submitOutputBuffers();
311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Submit output buffers to the decoder, submit input buffers to client
313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // to fill with data.
314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void resume();
315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
316349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    // Returns true iff input and output buffers are in play.
317349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool active() const { return mActive; }
318349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
319f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
326f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
327349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool mActive;
328349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingState);
330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
334f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::OutputPortSettingsChangedState : public ACodec::BaseState {
335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OutputPortSettingsChangedState(ACodec *codec);
336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
337f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
344f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(OutputPortSettingsChangedState);
346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
350f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingToIdleState : public ACodec::BaseState {
351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingToIdleState(ACodec *codec);
352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
353f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
362f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool mComponentNowIdle;
3665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingToIdleState);
368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
372f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToLoadedState : public ACodec::BaseState {
373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToLoadedState(ACodec *codec);
374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
375f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
381f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToLoadedState);
383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
387f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::FlushingState : public ACodec::BaseState {
388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    FlushingState(ACodec *codec);
389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
390f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
399f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool mFlushComplete[2];
401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(FlushingState);
405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
409f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ACodec()
410afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    : mQuirks(0),
411609b815a3131d22da38b2f452faa9f89daad4039Andy Hung      mNode(0),
4125778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mSentFormat(false),
4138db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu      mIsVideo(false),
414c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber      mIsEncoder(false),
415308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang      mUseMetadataOnEncoderOutput(false),
4169806555d3930be43e11106281dee354820ac1c88Andreas Huber      mShutdownInProgress(false),
41754b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar      mExplicitShutdown(false),
4189806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderDelay(0),
4199806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderPadding(0),
420e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang      mRotationDegrees(0),
4219806555d3930be43e11106281dee354820ac1c88Andreas Huber      mChannelMaskPresent(false),
422054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mChannelMask(0),
423054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mDequeueCounter(0),
424054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mStoreMetaDataInOutputBuffers(false),
425a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber      mMetaDataBuffersToSubmit(0),
42694ee4b708acfa941581160b267afb79192b1d816Chong Zhang      mRepeatFrameDelayUs(-1ll),
4272c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang      mMaxPtsGapUs(-1ll),
42837b2b389139ed638831e49708c947863eef631efRonghua Wu      mMaxFps(-1),
4292c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang      mTimePerFrameUs(-1ll),
430609b815a3131d22da38b2f452faa9f89daad4039Andy Hung      mTimePerCaptureUs(-1ll),
431ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad      mCreateInputBuffersSuspended(false),
432ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad      mTunneled(false) {
433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mUninitializedState = new UninitializedState(this);
434c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mLoadedState = new LoadedState(this);
435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mLoadedToIdleState = new LoadedToIdleState(this);
436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToExecutingState = new IdleToExecutingState(this);
437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingState = new ExecutingState(this);
438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOutputPortSettingsChangedState =
440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        new OutputPortSettingsChangedState(this);
441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingToIdleState = new ExecutingToIdleState(this);
443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToLoadedState = new IdleToLoadedState(this);
444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushingState = new FlushingState(this);
445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
447dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber    mInputEOSResult = OK;
448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeState(mUninitializedState);
450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
452f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::~ACodec() {
453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
455f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::setNotificationMessage(const sp<AMessage> &msg) {
456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mNotify = msg;
457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
459f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::initiateSetup(const sp<AMessage> &msg) {
460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setWhat(kWhatSetup);
4611d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    msg->setTarget(this);
462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
465a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Hubervoid ACodec::signalSetParameters(const sp<AMessage> &params) {
4661d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetParameters, this);
467a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->setMessage("params", params);
468a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->post();
469a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
470a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4715778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateAllocateComponent(const sp<AMessage> &msg) {
4725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatAllocateComponent);
4731d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    msg->setTarget(this);
4745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4755778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4775778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateConfigureComponent(const sp<AMessage> &msg) {
4785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatConfigureComponent);
4791d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    msg->setTarget(this);
4805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4815778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4831dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t ACodec::setSurface(const sp<Surface> &surface) {
4841dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetSurface, this);
4851dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    msg->setObject("surface", surface);
4861dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
4871dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    sp<AMessage> response;
4881dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    status_t err = msg->postAndAwaitResponse(&response);
4891dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
4901dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err == OK) {
4911dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        (void)response->findInt32("err", &err);
4921dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
4931dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    return err;
4941dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar}
4951dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
4967cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::initiateCreateInputSurface() {
4971d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatCreateInputSurface, this))->post();
4987cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
4997cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
500d291c222357303b9611cab89d0c3b047584ef377Chong Zhangvoid ACodec::initiateUsePersistentInputSurface(
501d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        const sp<PersistentSurface> &surface) {
502d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<AMessage> msg = new AMessage(kWhatUsePersistentInputSurface, this);
503d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    msg->setObject("input-surface", surface);
504d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    msg->post();
505d291c222357303b9611cab89d0c3b047584ef377Chong Zhang}
506d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5077cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::signalEndOfInputStream() {
5081d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatSignalEndOfInputStream, this))->post();
5097cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
5107cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
5115778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateStart() {
5121d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatStart, this))->post();
5135778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
5145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
515f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalFlush() {
5167a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] signalFlush", mComponentName.c_str());
5171d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatFlush, this))->post();
518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
520f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalResume() {
5211d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatResume, this))->post();
522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
524c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::initiateShutdown(bool keepComponentAllocated) {
5251d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatShutdown, this);
526c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->setInt32("keepComponentAllocated", keepComponentAllocated);
527c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->post();
52830358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar    if (!keepComponentAllocated) {
52930358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        // ensure shutdown completes in 3 seconds
5301d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar        (new AMessage(kWhatReleaseCodecInstance, this))->post(3000000);
53130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar    }
532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
534496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubervoid ACodec::signalRequestIDRFrame() {
5351d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatRequestIDRFrame, this))->post();
536496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
537496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5384dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
5394dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// Some codecs may return input buffers before having them processed.
5404dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// This causes a halt if we already signaled an EOS on the input
5414dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// port.  For now keep submitting an output buffer if there was an
5424dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// EOS on the input port, but not yet on the output port.
5434dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnarvoid ACodec::signalSubmitOutputMetaDataBufferIfEOS_workaround() {
5444dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    if (mPortEOS[kPortIndexInput] && !mPortEOS[kPortIndexOutput] &&
5454dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            mMetaDataBuffersToSubmit > 0) {
5461d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar        (new AMessage(kWhatSubmitOutputMetaDataBufferIfEOS, this))->post();
5474dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    }
5484dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar}
5494dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
5501dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t ACodec::handleSetSurface(const sp<Surface> &surface) {
5511dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // allow keeping unset surface
5521dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (surface == NULL) {
5531dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        if (mNativeWindow != NULL) {
5541dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            ALOGW("cannot unset a surface");
5551dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            return INVALID_OPERATION;
5561dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
5571dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return OK;
5581dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
5591dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
5601dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // allow keeping unset surface
5611dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mNativeWindow == NULL) {
5621dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGW("component was not configured with a surface");
5631dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return INVALID_OPERATION;
5641dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
5651dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
5661dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    ANativeWindow *nativeWindow = surface.get();
5671dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // if we have not yet started the codec, we can simply set the native window
5681dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mBuffers[kPortIndexInput].size() == 0) {
5691dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        mNativeWindow = surface;
5701dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return OK;
5711dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
5721dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
5731dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // we do not support changing a tunneled surface after start
5741dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mTunneled) {
5751dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGW("cannot change tunneled surface");
5761dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return INVALID_OPERATION;
5771dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
5781dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
5791dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    status_t err = setupNativeWindowSizeFormatAndUsage(nativeWindow);
5801dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != OK) {
5811dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
5821dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
5831dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
5841dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // get min undequeued count. We cannot switch to a surface that has a higher
5851dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // undequeued count than we allocated.
5861dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    int minUndequeuedBuffers = 0;
5871dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    err = nativeWindow->query(
5881dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            nativeWindow, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
5891dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            &minUndequeuedBuffers);
5901dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != 0) {
5911dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
5921dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                strerror(-err), -err);
5931dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
5941dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
5951dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (minUndequeuedBuffers > (int)mNumUndequeuedBuffers) {
5961dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGE("new surface holds onto more buffers (%d) than planned for (%zu)",
5971dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                minUndequeuedBuffers, mNumUndequeuedBuffers);
5981dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return BAD_VALUE;
5991dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6001dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
6011dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // we cannot change the number of output buffers while OMX is running
6021dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // set up surface to the same count
6031dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    Vector<BufferInfo> &buffers = mBuffers[kPortIndexOutput];
6041dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    ALOGV("setting up surface for %zu buffers", buffers.size());
6051dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
6061dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    err = native_window_set_buffer_count(nativeWindow, buffers.size());
6071dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != 0) {
6081dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
6091dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                -err);
6101dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
6111dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6121dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
613dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    // need to enable allocation when attaching
614dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    surface->getIGraphicBufferProducer()->allowAllocation(true);
615dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar
6161dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // for meta data mode, we move dequeud buffers to the new surface.
6171dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // for non-meta mode, we must move all registered buffers
6181dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    for (size_t i = 0; i < buffers.size(); ++i) {
6191dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        const BufferInfo &info = buffers[i];
6201dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        // skip undequeued buffers for meta data mode
6211dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        if (mStoreMetaDataInOutputBuffers
6221dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                && info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
6231dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            ALOGV("skipping buffer %p", info.mGraphicBuffer->getNativeBuffer());
6241dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            continue;
6251dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
6261dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGV("attaching buffer %p", info.mGraphicBuffer->getNativeBuffer());
6271dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
6281dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        err = surface->attachBuffer(info.mGraphicBuffer->getNativeBuffer());
6291dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        if (err != OK) {
6301dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            ALOGE("failed to attach buffer %p to the new surface: %s (%d)",
6311dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    info.mGraphicBuffer->getNativeBuffer(),
6321dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    strerror(-err), -err);
6331dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            return err;
6341dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
6351dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6361dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
6371dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // cancel undequeued buffers to new surface
6381dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (!mStoreMetaDataInOutputBuffers) {
6391dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        for (size_t i = 0; i < buffers.size(); ++i) {
6401dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            const BufferInfo &info = buffers[i];
6411dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
6421dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                ALOGV("canceling buffer %p", info.mGraphicBuffer->getNativeBuffer());
6431dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                err = nativeWindow->cancelBuffer(
6441dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                        nativeWindow, info.mGraphicBuffer->getNativeBuffer(), -1);
6451dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                if (err != OK) {
6461dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    ALOGE("failed to cancel buffer %p to the new surface: %s (%d)",
6471dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                            info.mGraphicBuffer->getNativeBuffer(),
6481dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                            strerror(-err), -err);
6491dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    return err;
6501dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                }
6511dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            }
6521dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
6531dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        // disallow further allocation
6541dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        (void)surface->getIGraphicBufferProducer()->allowAllocation(false);
6551dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6561dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
657484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar    // push blank buffers to previous window if requested
658484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar    if (mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown) {
659484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar        pushBlankBuffersToNativeWindow(mNativeWindow.get());
660484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar    }
661484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar
6621dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    mNativeWindow = nativeWindow;
6631dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    return OK;
6641dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar}
6651dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
666f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mDealer[portIndex] == NULL);
670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mBuffers[portIndex].isEmpty());
671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
674054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (mStoreMetaDataInOutputBuffers) {
675054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputMetaDataBuffers();
676054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
677054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputBuffersFromNativeWindow();
678054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
6795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
6805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
6815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
6825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = portIndex;
683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
6855778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err == OK) {
688609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGV("[%s] Allocating %u buffers of size %u on %s port",
6895778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mComponentName.c_str(),
6905778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    def.nBufferCountActual, def.nBufferSize,
6915778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    portIndex == kPortIndexInput ? "input" : "output");
692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            size_t totalSize = def.nBufferCountActual * def.nBufferSize;
6945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
6975778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
6985778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(mem.get() != NULL);
699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
700ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                BufferInfo info;
701ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                info.mStatus = BufferInfo::OWNED_BY_US;
702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
703afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                uint32_t requiresAllocateBufferBit =
704afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                    (portIndex == kPortIndexInput)
705afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        ? OMXCodec::kRequiresAllocateBufferOnInputPorts
706afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        : OMXCodec::kRequiresAllocateBufferOnOutputPorts;
7071065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
708308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                if ((portIndex == kPortIndexInput && (mFlags & kFlagIsSecure))
709308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        || mUseMetadataOnEncoderOutput) {
710ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    mem.clear();
711ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
712ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    void *ptr;
713ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->allocateBuffer(
714ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, def.nBufferSize, &info.mBufferID,
715ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            &ptr);
716ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
717308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    int32_t bufSize = mUseMetadataOnEncoderOutput ?
718308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                            (4 + sizeof(buffer_handle_t)) : def.nBufferSize;
719308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
720308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    info.mData = new ABuffer(ptr, bufSize);
721ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                } else if (mQuirks & requiresAllocateBufferBit) {
7225778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    err = mOMX->allocateBufferWithBackup(
723ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, mem, &info.mBufferID);
7245778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
725ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->useBuffer(mNode, portIndex, mem, &info.mBufferID);
726ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                }
727ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
728ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                if (mem != NULL) {
729ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    info.mData = new ABuffer(mem->pointer(), def.nBufferSize);
7305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
7311065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
7325778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mBuffers[portIndex].push(info);
7331065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            }
7341065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
7355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
7385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
7395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> notify = mNotify->dup();
742d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatBuffersAllocated);
7435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("portIndex", portIndex);
745eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
746eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    sp<PortDescription> desc = new PortDescription;
747eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
7485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
749eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        const BufferInfo &info = mBuffers[portIndex][i];
7505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
751eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        desc->addBuffer(info.mBufferID, info.mData);
752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
754eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    notify->setObject("portDesc", desc);
7555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->post();
7565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7601dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t ACodec::setupNativeWindowSizeFormatAndUsage(ANativeWindow *nativeWindow /* nonnull */) {
7611dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    OMX_PARAM_PORTDEFINITIONTYPE def;
7621dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    InitOMXParams(&def);
7631dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    def.nPortIndex = kPortIndexOutput;
7641dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
7651dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    status_t err = mOMX->getParameter(
7661dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
7671dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
7681dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != OK) {
7691dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
7701dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7711dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
7721dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    OMX_U32 usage = 0;
7731dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
7741dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != 0) {
7751dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGW("querying usage flags from OMX IL component failed: %d", err);
7761dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        // XXX: Currently this error is logged, but not fatal.
7771dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        usage = 0;
7781dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7791dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    int omxUsage = usage;
7801dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
7811dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mFlags & kFlagIsGrallocUsageProtected) {
7821dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        usage |= GRALLOC_USAGE_PROTECTED;
7831dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7841dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
785b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar    usage |= GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP;
786b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar
7871dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    ALOGV("gralloc usage: %#x(OMX) => %#x(ACodec)", omxUsage, usage);
7881dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    return setNativeWindowSizeFormatAndUsage(
7891dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            nativeWindow,
7901dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            def.format.video.nFrameWidth,
7911dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            def.format.video.nFrameHeight,
7921dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            def.format.video.eColorFormat,
7931dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            mRotationDegrees,
7941dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            usage);
7951dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar}
7961dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
7971dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t ACodec::configureOutputBuffersFromNativeWindow(
7981dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        OMX_U32 *bufferCount, OMX_U32 *bufferSize,
7991dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        OMX_U32 *minUndequeuedBuffers) {
8001dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    OMX_PARAM_PORTDEFINITIONTYPE def;
8011dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    InitOMXParams(&def);
8021dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    def.nPortIndex = kPortIndexOutput;
8031dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
8041dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    status_t err = mOMX->getParameter(
8051dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
8061dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
8071dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err == OK) {
8081dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        err = setupNativeWindowSizeFormatAndUsage(mNativeWindow.get());
8091dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
8101dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != OK) {
8111dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
8121dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
8131dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
814ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // Exits here for tunneled video playback codecs -- i.e. skips native window
815ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // buffer allocation step as this is managed by the tunneled OMX omponent
816ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // itself and explicitly sets def.nBufferCountActual to 0.
817ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    if (mTunneled) {
818ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        ALOGV("Tunneled Playback: skipping native window buffer allocation.");
819ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        def.nBufferCountActual = 0;
820ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        err = mOMX->setParameter(
821ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
822ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
823ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *minUndequeuedBuffers = 0;
824ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *bufferCount = 0;
825ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *bufferSize = 0;
826ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        return err;
827ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    }
828ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
829054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *minUndequeuedBuffers = 0;
830258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    err = mNativeWindow->query(
831258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
832054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (int *)minUndequeuedBuffers);
833258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
834258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    if (err != 0) {
83529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
836258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                strerror(-err), -err);
837258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        return err;
838258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
839258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
840e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // FIXME: assume that surface is controlled by app (native window
841e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // returns the number for the case when surface is not controlled by app)
8421faa41704e0b976e546321effcb09a85767d51baLajos Molnar    // FIXME2: This means that minUndeqeueudBufs can be 1 larger than reported
8431faa41704e0b976e546321effcb09a85767d51baLajos Molnar    // For now, try to allocate 1 more buffer, but don't fail if unsuccessful
844e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar
845e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // Use conservative allocation while also trying to reduce starvation
846e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //
847e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // 1. allocate at least nBufferCountMin + minUndequeuedBuffers - that is the
848e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //    minimum needed for the consumer to be able to work
849e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // 2. try to allocate two (2) additional buffers to reduce starvation from
850e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //    the consumer
8511faa41704e0b976e546321effcb09a85767d51baLajos Molnar    //    plus an extra buffer to account for incorrect minUndequeuedBufs
8521faa41704e0b976e546321effcb09a85767d51baLajos Molnar    for (OMX_U32 extraBuffers = 2 + 1; /* condition inside loop */; extraBuffers--) {
853e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        OMX_U32 newBufferCount =
854e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            def.nBufferCountMin + *minUndequeuedBuffers + extraBuffers;
855258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        def.nBufferCountActual = newBufferCount;
856258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        err = mOMX->setParameter(
857258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
858258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
859e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        if (err == OK) {
860e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            *minUndequeuedBuffers += extraBuffers;
861e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            break;
862e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        }
863e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar
864609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGW("[%s] setting nBufferCountActual to %u failed: %d",
865e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar                mComponentName.c_str(), newBufferCount, err);
866e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        /* exit condition */
867e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        if (extraBuffers == 0) {
868258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            return err;
869258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        }
870258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
871258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffer_count(
873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(), def.nBufferCountActual);
874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
87629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                -err);
878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
881054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferCount = def.nBufferCountActual;
882054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferSize =  def.nBufferSize;
883054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
884054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
885054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
886054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputBuffersFromNativeWindow() {
887054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
888054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
889054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
890054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
891054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
892e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    mNumUndequeuedBuffers = minUndequeuedBuffers;
893054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
8943298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia    if (!mStoreMetaDataInOutputBuffers) {
8953298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia        static_cast<Surface*>(mNativeWindow.get())
8963298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia                ->getIGraphicBufferProducer()->allowAllocation(true);
8973298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia    }
8983298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia
899609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Allocating %u buffers from a native window of size %u on "
900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         "output port",
901054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount, bufferSize);
902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Dequeue buffers and send them to OMX
904054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
9058ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev        ANativeWindowBuffer *buf;
9061e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
90829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
91374006804065941841883c4b46ee785070164023fJamie Gennis        BufferInfo info;
91474006804065941841883c4b46ee785070164023fJamie Gennis        info.mStatus = BufferInfo::OWNED_BY_US;
915054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(NULL /* data */, bufferSize /* capacity */);
91674006804065941841883c4b46ee785070164023fJamie Gennis        info.mGraphicBuffer = graphicBuffer;
91774006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].push(info);
91874006804065941841883c4b46ee785070164023fJamie Gennis
919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferId;
920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &bufferId);
922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
923609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGE("registering GraphicBuffer %u with OMX IL component failed: "
92474006804065941841883c4b46ee785070164023fJamie Gennis                 "%d", i, err);
925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
92874006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
92974006804065941841883c4b46ee785070164023fJamie Gennis
930609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGV("[%s] Registered graphic buffer with ID %u (pointer = %p)",
931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mComponentName.c_str(),
932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             bufferId, graphicBuffer.get());
933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelStart;
936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelEnd;
937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // If an error occurred while dequeuing we need to cancel any buffers
940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // that were dequeued.
941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelStart = 0;
94274006804065941841883c4b46ee785070164023fJamie Gennis        cancelEnd = mBuffers[kPortIndexOutput].size();
943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
944054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // Return the required minimum undequeued buffers to the native window.
945054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelStart = bufferCount - minUndequeuedBuffers;
946054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelEnd = bufferCount;
947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
9513fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        status_t error = cancelBufferToNativeWindow(info);
9523fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        if (err == 0) {
9533fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia            err = error;
9543fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        }
955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9573298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia    if (!mStoreMetaDataInOutputBuffers) {
9583298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia        static_cast<Surface*>(mNativeWindow.get())
9593298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia                ->getIGraphicBufferProducer()->allowAllocation(false);
9603298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia    }
9613298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia
962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
965054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputMetaDataBuffers() {
966054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
967054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
968054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
969054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
970054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
971e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    mNumUndequeuedBuffers = minUndequeuedBuffers;
972054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
973609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Allocating %u meta buffers on output port",
974054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount);
975054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
976054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    size_t totalSize = bufferCount * 8;
977054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mDealer[kPortIndexOutput] = new MemoryDealer(totalSize, "ACodec");
978054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
979054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // Dequeue buffers and send them to OMX
980054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
981054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo info;
982054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
983054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mGraphicBuffer = NULL;
984054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mDequeuedAt = mDequeueCounter;
985054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
986054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        sp<IMemory> mem = mDealer[kPortIndexOutput]->allocate(
987054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                sizeof(struct VideoDecoderOutputMetaData));
988054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(mem.get() != NULL);
989054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(mem->pointer(), mem->size());
990054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
991054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // we use useBuffer for metadata regardless of quirks
992054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        err = mOMX->useBuffer(
993054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mNode, kPortIndexOutput, mem, &info.mBufferID);
994054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
995054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        mBuffers[kPortIndexOutput].push(info);
996054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
997609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGV("[%s] allocated meta buffer with ID %u (pointer = %p)",
998054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mComponentName.c_str(), info.mBufferID, mem->pointer());
999054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1000054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1001054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mMetaDataBuffersToSubmit = bufferCount - minUndequeuedBuffers;
1002054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
1003054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
1004054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1005054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::submitOutputMetaDataBuffer() {
1006054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mStoreMetaDataInOutputBuffers);
1007054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mMetaDataBuffersToSubmit == 0)
1008054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return OK;
1009054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1010054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *info = dequeueBufferFromNativeWindow();
1011054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (info == NULL)
1012054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return ERROR_IO;
1013054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1014609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] submitting output meta buffer ID %u for graphic buffer %p",
1015054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          mComponentName.c_str(), info->mBufferID, info->mGraphicBuffer.get());
1016054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1017054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    --mMetaDataBuffersToSubmit;
1018054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK_EQ(mOMX->fillBuffer(mNode, info->mBufferID),
1019054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             (status_t)OK);
1020054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1021054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
1022054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return OK;
1023054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
1024054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1025f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
1026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
1027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1028609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Calling cancelBuffer on buffer %u",
1029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mComponentName.c_str(), info->mBufferID);
1030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int err = mNativeWindow->cancelBuffer(
10321e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        mNativeWindow.get(), info->mGraphicBuffer.get(), -1);
1033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10343fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia    ALOGW_IF(err != 0, "[%s] can not return buffer %u to native window",
10353fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia            mComponentName.c_str(), info->mBufferID);
1036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
1038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10393fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia    return err;
1040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1042f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
10438ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev    ANativeWindowBuffer *buf;
1044054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mNativeWindow.get() != NULL);
1045ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
1046ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    if (mTunneled) {
1047ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        ALOGW("dequeueBufferFromNativeWindow() should not be called in tunnel"
1048ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad              " video playback mode mode!");
1049ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        return NULL;
1050ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    }
1051ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
1052dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    do {
1053dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        if (native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf) != 0) {
1054dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            ALOGE("dequeueBuffer failed.");
1055dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            return NULL;
1056dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        }
1057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1058dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        bool stale = false;
1059dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
1060dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
1061dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar
1062dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            if (info->mGraphicBuffer != NULL &&
1063dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                info->mGraphicBuffer->handle == buf->handle) {
1064dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // Since consumers can attach buffers to BufferQueues, it is possible
1065dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // that a known yet stale buffer can return from a surface that we
1066dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // once used.  We can simply ignore this as we have already dequeued
1067dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // this buffer properly.  NOTE: this does not eliminate all cases,
1068dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // e.g. it is possible that we have queued the valid buffer to the
1069dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // NW, and a stale copy of the same buffer gets dequeued - which will
1070dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // be treated as the valid buffer by ACodec.
1071dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                if (info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
1072dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                    ALOGI("dequeued stale buffer %p. discarding", buf);
1073dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                    stale = true;
1074dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                    break;
1075dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                }
1076dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                ALOGV("dequeued buffer %p", info->mGraphicBuffer->getNativeBuffer());
1077dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                info->mStatus = BufferInfo::OWNED_BY_US;
1078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1079dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                return info;
1080dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            }
1081dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        }
1082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1083dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // It is also possible to receive a previously unregistered buffer
1084dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // in non-meta mode. These should be treated as stale buffers. The
1085dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // same is possible in meta mode, in which case, it will be treated
1086dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // as a normal buffer, which is not desirable.
1087dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // TODO: fix this.
1088dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        if (!stale && !mStoreMetaDataInOutputBuffers) {
1089dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            ALOGI("dequeued unrecognized (stale) buffer %p. discarding", buf);
1090dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            stale = true;
1091dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        }
1092dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        if (stale) {
1093dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            // TODO: detach stale buffer, but there is no API yet to do it.
1094dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            buf = NULL;
1095f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1096dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    } while (buf == NULL);
1097054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1098dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    // get oldest undequeued buffer
1099dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    BufferInfo *oldest = NULL;
1100dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
1101dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        BufferInfo *info =
1102dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            &mBuffers[kPortIndexOutput].editItemAt(i);
1103054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW &&
1104054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (oldest == NULL ||
1105054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             // avoid potential issues from counter rolling over
1106054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mDequeueCounter - info->mDequeuedAt >
1107054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    mDequeueCounter - oldest->mDequeuedAt)) {
1108054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            oldest = info;
1109054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
1110054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1111054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1112054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (oldest) {
1113054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(mStoreMetaDataInOutputBuffers);
1114054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1115054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // discard buffer in LRU info and replace with new buffer
1116054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mGraphicBuffer = new GraphicBuffer(buf, false);
1117054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mStatus = BufferInfo::OWNED_BY_US;
1118054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1119d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        mOMX->updateGraphicBufferInMeta(
1120d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                mNode, kPortIndexOutput, oldest->mGraphicBuffer,
1121d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                oldest->mBufferID);
1122054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1123d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        VideoDecoderOutputMetaData *metaData =
1124d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar            reinterpret_cast<VideoDecoderOutputMetaData *>(
1125d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                    oldest->mData->base());
1126d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        CHECK_EQ(metaData->eType, kMetadataBufferTypeGrallocSource);
1127d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar
1128d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
1129ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                (unsigned)(oldest - &mBuffers[kPortIndexOutput][0]),
1130054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mDequeueCounter - oldest->mDequeuedAt,
1131d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                metaData->pHandle,
1132d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                oldest->mGraphicBuffer->handle, oldest->mData->base());
1133054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1134054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return oldest;
1135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
1138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
1140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1142f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
1143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[portIndex].size(); i-- > 0;) {
1144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, freeBuffer(portIndex, i));
1145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDealer[portIndex].clear();
1148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1152349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huberstatus_t ACodec::freeOutputBuffersNotOwnedByComponent() {
1153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
1154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
1155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
1156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
11572ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // At this time some buffers may still be with the component
11582ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // or being drained.
11592ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT &&
11602ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar            info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) {
1161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK, freeBuffer(kPortIndexOutput, i));
1162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1168f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
1169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
1170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(info->mStatus == BufferInfo::OWNED_BY_US
1172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
1173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput && mNativeWindow != NULL
1175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && info->mStatus == BufferInfo::OWNED_BY_US) {
11763fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        cancelBufferToNativeWindow(info);
1177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(mOMX->freeBuffer(
1180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, portIndex, info->mBufferID),
1181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
1182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mBuffers[portIndex].removeAt(i);
1184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1188f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::findBufferByID(
1189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        uint32_t portIndex, IOMX::buffer_id bufferID,
1190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ssize_t *index) {
1191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
1192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
1193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mBufferID == bufferID) {
1195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (index != NULL) {
1196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                *index = i;
1197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
1199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
1203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
1205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
12075778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setComponentRole(
1208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        bool isEncoder, const char *mime) {
1209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    struct MimeToRole {
1210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime;
1211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *decoderRole;
1212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *encoderRole;
1213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
1214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const MimeToRole kMimeToRole[] = {
1216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG,
1217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.mp3", "audio_encoder.mp3" },
12182944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
12192944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp1", "audio_encoder.mp1" },
12202944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
12212944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp2", "audio_encoder.mp2" },
1222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_NB,
1223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrnb", "audio_encoder.amrnb" },
1224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_WB,
1225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrwb", "audio_encoder.amrwb" },
1226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AAC,
1227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.aac", "audio_encoder.aac" },
1228729de186450f78c099637e1fce743fe531862c52Andreas Huber        { MEDIA_MIMETYPE_AUDIO_VORBIS,
1229729de186450f78c099637e1fce743fe531862c52Andreas Huber            "audio_decoder.vorbis", "audio_encoder.vorbis" },
1230bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian        { MEDIA_MIMETYPE_AUDIO_OPUS,
1231bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian            "audio_decoder.opus", "audio_encoder.opus" },
1232c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_MLAW,
1233c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" },
1234c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_ALAW,
1235c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711alaw", "audio_encoder.g711alaw" },
1236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_AVC,
1237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.avc", "video_encoder.avc" },
12382472b1c0d63454e5d90a982bd6c555de6c3127bdRachad        { MEDIA_MIMETYPE_VIDEO_HEVC,
12392472b1c0d63454e5d90a982bd6c555de6c3127bdRachad            "video_decoder.hevc", "video_encoder.hevc" },
1240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_MPEG4,
1241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.mpeg4", "video_encoder.mpeg4" },
1242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_H263,
1243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.h263", "video_encoder.h263" },
124494705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP8,
124594705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp8", "video_encoder.vp8" },
124694705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP9,
124794705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp9", "video_encoder.vp9" },
1248ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        { MEDIA_MIMETYPE_AUDIO_RAW,
1249ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            "audio_decoder.raw", "audio_encoder.raw" },
12502f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        { MEDIA_MIMETYPE_AUDIO_FLAC,
12512f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            "audio_decoder.flac", "audio_encoder.flac" },
1252ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        { MEDIA_MIMETYPE_AUDIO_MSGSM,
1253ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen            "audio_decoder.gsm", "audio_encoder.gsm" },
1254774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu        { MEDIA_MIMETYPE_VIDEO_MPEG2,
1255774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu            "video_decoder.mpeg2", "video_encoder.mpeg2" },
125697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        { MEDIA_MIMETYPE_AUDIO_AC3,
125797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            "audio_decoder.ac3", "audio_encoder.ac3" },
12588a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        { MEDIA_MIMETYPE_AUDIO_EAC3,
12598a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            "audio_decoder.eac3", "audio_encoder.eac3" },
1260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
1261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const size_t kNumMimeToRole =
1263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
1264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    size_t i;
1266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (i = 0; i < kNumMimeToRole; ++i) {
1267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcasecmp(mime, kMimeToRole[i].mime)) {
1268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (i == kNumMimeToRole) {
12735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_UNSUPPORTED;
1274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    const char *role =
1277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        isEncoder ? kMimeToRole[i].encoderRole
1278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                  : kMimeToRole[i].decoderRole;
1279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (role != NULL) {
1281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_PARAM_COMPONENTROLETYPE roleParams;
1282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        InitOMXParams(&roleParams);
1283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        strncpy((char *)roleParams.cRole,
1285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                role, OMX_MAX_STRINGNAME_SIZE - 1);
1286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
1288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->setParameter(
1290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamStandardComponentRole,
1291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &roleParams, sizeof(roleParams));
1292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
12945ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("[%s] Failed to set standard component role '%s'.",
1295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 mComponentName.c_str(), role);
12965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
1298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
13005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
1302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
13045778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::configureCodec(
1305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime, const sp<AMessage> &msg) {
13065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t encoder;
13075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("encoder", &encoder)) {
13085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        encoder = false;
13095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1311e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    sp<AMessage> inputFormat = new AMessage();
13124e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    sp<AMessage> outputFormat = mNotify->dup(); // will use this for kWhatOutputFormatChanged
1313e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
13145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mIsEncoder = encoder;
1315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
13168db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu
13175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setComponentRole(encoder /* isEncoder */, mime);
13185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
13205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
13215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
13225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitRate = 0;
13242f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    // FLAC encoder doesn't need a bitrate, other encoders do
13252f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
13262f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            && !msg->findInt32("bitrate", &bitRate)) {
13275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
13285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
13295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1330d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    int32_t storeMeta;
1331d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (encoder
1332d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && msg->findInt32("store-metadata-in-buffers", &storeMeta)
1333d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && storeMeta != 0) {
1334d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE);
1335d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1336d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (err != OK) {
1337308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              ALOGE("[%s] storeMetaDataInBuffers (input) failed w/ err %d",
1338308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    mComponentName.c_str(), err);
1339d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1340308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              return err;
1341308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang          }
1342308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang      }
1343d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1344308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t prependSPSPPS = 0;
13453a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    if (encoder
13463a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
13473a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && prependSPSPPS != 0) {
13483a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        OMX_INDEXTYPE index;
13493a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        err = mOMX->getExtensionIndex(
13503a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                mNode,
13513a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                "OMX.google.android.index.prependSPSPPSToIDRFrames",
13523a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                &index);
13533a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
13543a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err == OK) {
13553a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            PrependSPSPPSToIDRFramesParams params;
13563a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            InitOMXParams(&params);
13573a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            params.bEnable = OMX_TRUE;
13583a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
13593a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            err = mOMX->setParameter(
13603a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                    mNode, index, &params, sizeof(params));
13613a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
13623a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
13633a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err != OK) {
13643a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            ALOGE("Encoder could not be configured to emit SPS/PPS before "
13653a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                  "IDR frames. (err %d)", err);
13663a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
13673a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            return err;
13683a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
13693a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    }
13703a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
1371308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // Only enable metadata mode on encoder output if encoder can prepend
1372308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // sps/pps to idr frames, since in metadata mode the bitstream is in an
1373308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // opaque handle, to which we don't have access.
1374308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t video = !strncasecmp(mime, "video/", 6);
13758db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    mIsVideo = video;
1376308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (encoder && video) {
1377308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS
1378308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && msg->findInt32("store-metadata-in-buffers-output", &storeMeta)
1379308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && storeMeta != 0);
1380308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1381308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, enable);
1382308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1383308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        if (err != OK) {
1384308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            ALOGE("[%s] storeMetaDataInBuffers (output) failed w/ err %d",
1385308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                mComponentName.c_str(), err);
1386308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = 0;
1387308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        } else {
1388308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = enable;
1389308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        }
1390a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
1391a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (!msg->findInt64(
1392a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    "repeat-previous-frame-after",
1393a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    &mRepeatFrameDelayUs)) {
1394a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            mRepeatFrameDelayUs = -1ll;
1395a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
139694ee4b708acfa941581160b267afb79192b1d816Chong Zhang
139794ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (!msg->findInt64("max-pts-gap-to-encoder", &mMaxPtsGapUs)) {
13982c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mMaxPtsGapUs = -1ll;
13992c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
14002c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
140137b2b389139ed638831e49708c947863eef631efRonghua Wu        if (!msg->findFloat("max-fps-to-encoder", &mMaxFps)) {
140237b2b389139ed638831e49708c947863eef631efRonghua Wu            mMaxFps = -1;
140337b2b389139ed638831e49708c947863eef631efRonghua Wu        }
140437b2b389139ed638831e49708c947863eef631efRonghua Wu
14052c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (!msg->findInt64("time-lapse", &mTimePerCaptureUs)) {
14062c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mTimePerCaptureUs = -1ll;
140794ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
140872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
140972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (!msg->findInt32(
141072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    "create-input-buffers-suspended",
141172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    (int32_t*)&mCreateInputBuffersSuspended)) {
141272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mCreateInputBuffersSuspended = false;
141372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
1414308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    }
1415308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
14163a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar    // NOTE: we only use native window for video decoders
1417054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    sp<RefBase> obj;
14180d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    bool haveNativeWindow = msg->findObject("native-window", &obj)
14193a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            && obj != NULL && video && !encoder;
1420054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mStoreMetaDataInOutputBuffers = false;
1421e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if (video && !encoder) {
1422e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        inputFormat->setInt32("adaptive-playback", false);
14231713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang
14241713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        int32_t usageProtected;
14251713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        if (msg->findInt32("protected", &usageProtected) && usageProtected) {
14261713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            if (!haveNativeWindow) {
14271713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang                ALOGE("protected output buffers must be sent to an ANativeWindow");
14281713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang                return PERMISSION_DENIED;
14291713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            }
14301713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            mFlags |= kFlagIsGrallocUsageProtected;
14311713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
14321713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        }
1433e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
14343a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar    if (haveNativeWindow) {
14351de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar        sp<ANativeWindow> nativeWindow =
14361de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar            static_cast<ANativeWindow *>(static_cast<Surface *>(obj.get()));
14375a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
14386597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        // START of temporary support for automatic FRC - THIS WILL BE REMOVED
14396597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        int32_t autoFrc;
14406597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        if (msg->findInt32("auto-frc", &autoFrc)) {
14416597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            bool enabled = autoFrc;
14426597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            OMX_CONFIG_BOOLEANTYPE config;
14436597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            InitOMXParams(&config);
14446597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            config.bEnabled = (OMX_BOOL)enabled;
14456597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            status_t temp = mOMX->setConfig(
14466597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                    mNode, (OMX_INDEXTYPE)OMX_IndexConfigAutoFramerateConversion,
14476597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                    &config, sizeof(config));
14486597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            if (temp == OK) {
14496597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                outputFormat->setInt32("auto-frc", enabled);
14506597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            } else if (enabled) {
14516597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                ALOGI("codec does not support requested auto-frc (err %d)", temp);
14526597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            }
14536597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        }
14546597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        // END of temporary support for automatic FRC
14556597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar
14565a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        int32_t tunneled;
14575a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        if (msg->findInt32("feature-tunneled-playback", &tunneled) &&
14585a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            tunneled != 0) {
14595a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            ALOGI("Configuring TUNNELED video playback.");
1460ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            mTunneled = true;
14615a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
146297827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad            int32_t audioHwSync = 0;
146397827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad            if (!msg->findInt32("audio-hw-sync", &audioHwSync)) {
14645a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGW("No Audio HW Sync provided for video tunnel");
14655a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            }
14665a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            err = configureTunneledVideoPlayback(audioHwSync, nativeWindow);
14675a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (err != OK) {
146897827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad                ALOGE("configureTunneledVideoPlayback(%d,%p) failed!",
14695a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        audioHwSync, nativeWindow.get());
14705a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                return err;
1471fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
1472fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1473d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            int32_t maxWidth = 0, maxHeight = 0;
1474d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            if (msg->findInt32("max-width", &maxWidth) &&
1475d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    msg->findInt32("max-height", &maxHeight)) {
1476d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad
1477d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                err = mOMX->prepareForAdaptivePlayback(
1478d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                        mNode, kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight);
1479d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                if (err != OK) {
1480d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    ALOGW("[%s] prepareForAdaptivePlayback failed w/ err %d",
1481d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                            mComponentName.c_str(), err);
14823a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    // allow failure
14833a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    err = OK;
1484d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                } else {
1485d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("max-width", maxWidth);
1486d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("max-height", maxHeight);
1487d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("adaptive-playback", true);
1488d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                }
1489d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            }
14905a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        } else {
1491ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            ALOGV("Configuring CPU controlled video playback.");
1492ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            mTunneled = false;
1493ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
14943fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // Explicity reset the sideband handle of the window for
14953fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // non-tunneled video in case the window was previously used
14963fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // for a tunneled video playback.
14973fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            err = native_window_set_sideband_stream(nativeWindow.get(), NULL);
14983fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            if (err != OK) {
14993fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad                ALOGE("set_sideband_stream(NULL) failed! (err %d).", err);
15003fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad                return err;
15013fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            }
15023fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad
15035a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            // Always try to enable dynamic output buffers on native surface
15045a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            err = mOMX->storeMetaDataInBuffers(
15055a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    mNode, kPortIndexOutput, OMX_TRUE);
15065a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (err != OK) {
15075a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d",
1508fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        mComponentName.c_str(), err);
1509e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
15105a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // if adaptive playback has been requested, try JB fallback
15115a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // NOTE: THIS FALLBACK MECHANISM WILL BE REMOVED DUE TO ITS
15125a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // LARGE MEMORY REQUIREMENT
15135a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
15145a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // we will not do adaptive playback on software accessed
15155a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // surfaces as they never had to respond to changes in the
15165a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // crop window, and we don't trust that they will be able to.
15175a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                int usageBits = 0;
15185a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                bool canDoAdaptivePlayback;
15195a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
15205a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                if (nativeWindow->query(
15215a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        nativeWindow.get(),
15225a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        NATIVE_WINDOW_CONSUMER_USAGE_BITS,
15235a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        &usageBits) != OK) {
15245a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    canDoAdaptivePlayback = false;
15255a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                } else {
15265a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    canDoAdaptivePlayback =
15275a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        (usageBits &
15285a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                                (GRALLOC_USAGE_SW_READ_MASK |
15295a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                                 GRALLOC_USAGE_SW_WRITE_MASK)) == 0;
15305a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                }
15315a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
15325a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                int32_t maxWidth = 0, maxHeight = 0;
15335a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                if (canDoAdaptivePlayback &&
15345a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        msg->findInt32("max-width", &maxWidth) &&
15355a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        msg->findInt32("max-height", &maxHeight)) {
15365a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    ALOGV("[%s] prepareForAdaptivePlayback(%dx%d)",
15375a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mComponentName.c_str(), maxWidth, maxHeight);
15385a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
15395a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    err = mOMX->prepareForAdaptivePlayback(
15405a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mNode, kPortIndexOutput, OMX_TRUE, maxWidth,
15415a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            maxHeight);
15425a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    ALOGW_IF(err != OK,
15435a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            "[%s] prepareForAdaptivePlayback failed w/ err %d",
15445a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mComponentName.c_str(), err);
15455a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
15465a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    if (err == OK) {
15475a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("max-width", maxWidth);
15485a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("max-height", maxHeight);
15495a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("adaptive-playback", true);
15505a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    }
1551e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
15525a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // allow failure
15535a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                err = OK;
15545a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            } else {
15555a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGV("[%s] storeMetaDataInBuffers succeeded",
15565a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        mComponentName.c_str());
15575a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                mStoreMetaDataInOutputBuffers = true;
15585a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                inputFormat->setInt32("adaptive-playback", true);
1559fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
15600167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber
15615a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            int32_t push;
15625a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (msg->findInt32("push-blank-buffers-on-shutdown", &push)
15635a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    && push != 0) {
15645a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
15655a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            }
15660167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        }
1567e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang
1568e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        int32_t rotationDegrees;
1569e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        if (msg->findInt32("rotation-degrees", &rotationDegrees)) {
1570e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            mRotationDegrees = rotationDegrees;
1571e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        } else {
1572e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            mRotationDegrees = 0;
1573e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        }
1574054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1575054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1576308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (video) {
15773a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // determine need for software renderer
15783a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        bool usingSwRenderer = false;
15793a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (haveNativeWindow && mComponentName.startsWith("OMX.google.")) {
15803a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            usingSwRenderer = true;
15813a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            haveNativeWindow = false;
15823a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
15833a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
15845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (encoder) {
15855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupVideoEncoder(mime, msg);
15865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
15870d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            err = setupVideoDecoder(mime, msg, haveNativeWindow);
15885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15893a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
15903a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (err != OK) {
15913a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            return err;
15923a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
15933a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
15943a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (haveNativeWindow) {
15951de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar            mNativeWindow = static_cast<Surface *>(obj.get());
15961de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar            CHECK(mNativeWindow != NULL);
15973a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
15983a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
15993a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // initialize native window now to get actual output format
16003a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // TODO: this is needed for some encoders even though they don't use native window
16013a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        CHECK_EQ((status_t)OK, initNativeWindow());
16023a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
16033a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // fallback for devices that do not handle flex-YUV for native buffers
16043a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (haveNativeWindow) {
16053a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            int32_t requestedColorFormat = OMX_COLOR_FormatUnused;
16063a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            if (msg->findInt32("color-format", &requestedColorFormat) &&
16073a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    requestedColorFormat == OMX_COLOR_FormatYUV420Flexible) {
16083a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                CHECK_EQ(getPortFormat(kPortIndexOutput, outputFormat), (status_t)OK);
16093a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                int32_t colorFormat = OMX_COLOR_FormatUnused;
16103a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                OMX_U32 flexibleEquivalent = OMX_COLOR_FormatUnused;
16113a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                CHECK(outputFormat->findInt32("color-format", &colorFormat));
16123a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                ALOGD("[%s] Requested output format %#x and got %#x.",
16133a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        mComponentName.c_str(), requestedColorFormat, colorFormat);
16143a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                if (!isFlexibleColorFormat(
16153a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                                mOMX, mNode, colorFormat, haveNativeWindow, &flexibleEquivalent)
16163a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        || flexibleEquivalent != (OMX_U32)requestedColorFormat) {
16173a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    // device did not handle flex-YUV request for native window, fall back
16183a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    // to SW renderer
16193a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    ALOGI("[%s] Falling back to software renderer", mComponentName.c_str());
16203a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    mNativeWindow.clear();
16213a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    haveNativeWindow = false;
16223a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    usingSwRenderer = true;
16233a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    if (mStoreMetaDataInOutputBuffers) {
16243a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, OMX_FALSE);
16253a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        mStoreMetaDataInOutputBuffers = false;
16263a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        // TODO: implement adaptive-playback support for bytebuffer mode.
16273a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        // This is done by SW codecs, but most HW codecs don't support it.
16283a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        inputFormat->setInt32("adaptive-playback", false);
16293a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
16303a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    if (err == OK) {
16313a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        err = mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
16323a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
16333a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    if (mFlags & kFlagIsGrallocUsageProtected) {
16343a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        // fallback is not supported for protected playback
16353a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        err = PERMISSION_DENIED;
16363a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    } else if (err == OK) {
16373a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        err = setupVideoDecoder(mime, msg, false);
16383a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
16393a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                }
16403a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            }
16413a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
16423a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
16433a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (usingSwRenderer) {
16443a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            outputFormat->setInt32("using-sw-renderer", 1);
16453a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
164642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
164742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        int32_t numChannels, sampleRate;
164842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        if (!msg->findInt32("channel-count", &numChannels)
164942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
165042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // Since we did not always check for these, leave them optional
165142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // and have the decoder figure it all out.
165242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = OK;
165342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        } else {
165442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = setupRawAudioFormat(
165542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    encoder ? kPortIndexInput : kPortIndexOutput,
165642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    sampleRate,
165742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    numChannels);
165842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        }
1659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
1660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t numChannels, sampleRate;
16615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)
16625778822d86b0337407514b9372562b86edfa91cdAndreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
16635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
16645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
1665aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            int32_t isADTS, aacProfile;
1666b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            int32_t sbrMode;
16678045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            int32_t maxOutputChannelCount;
16682965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            int32_t pcmLimiterEnable;
16698045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            drcParams_t drc;
1670ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            if (!msg->findInt32("is-adts", &isADTS)) {
1671ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                isADTS = 0;
1672ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
1673aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (!msg->findInt32("aac-profile", &aacProfile)) {
1674aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                aacProfile = OMX_AUDIO_AACObjectNull;
1675aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
1676b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            if (!msg->findInt32("aac-sbr-mode", &sbrMode)) {
1677b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                sbrMode = -1;
1678b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            }
1679ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
16808045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-max-output-channel_count", &maxOutputChannelCount)) {
16818045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                maxOutputChannelCount = -1;
16828045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
16832965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            if (!msg->findInt32("aac-pcm-limiter-enable", &pcmLimiterEnable)) {
16842965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                // value is unknown
16852965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                pcmLimiterEnable = -1;
16862965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            }
16878045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-encoded-target-level", &drc.encodedTargetLevel)) {
16888045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
16898045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.encodedTargetLevel = -1;
16908045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
16918045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-cut-level", &drc.drcCut)) {
16928045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
16938045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.drcCut = -1;
16948045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
16958045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-boost-level", &drc.drcBoost)) {
16968045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
16978045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.drcBoost = -1;
16988045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
16998045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-heavy-compression", &drc.heavyCompression)) {
17008045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
17018045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.heavyCompression = -1;
17028045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
17038045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-target-ref-level", &drc.targetRefLevel)) {
17048045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
17058045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.targetRefLevel = -1;
17068045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
17078045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi
1708ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            err = setupAACCodec(
17094471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    encoder, numChannels, sampleRate, bitRate, aacProfile,
17102965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                    isADTS != 0, sbrMode, maxOutputChannelCount, drc,
17112965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                    pcmLimiterEnable);
17125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
1713729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
17145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
1715729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
17165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
1717729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
1718729de186450f78c099637e1fce743fe531862c52Andreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
1719729de186450f78c099637e1fce743fe531862c52Andreas Huber        // These are PCM-like formats with a fixed sample rate but
1720729de186450f78c099637e1fce743fe531862c52Andreas Huber        // a variable number of channels.
1721729de186450f78c099637e1fce743fe531862c52Andreas Huber
1722729de186450f78c099637e1fce743fe531862c52Andreas Huber        int32_t numChannels;
17235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)) {
17245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
17255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
172617c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            int32_t sampleRate;
172717c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            if (!msg->findInt32("sample-rate", &sampleRate)) {
172817c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen                sampleRate = 8000;
172917c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            }
173017c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            err = setupG711Codec(encoder, sampleRate, numChannels);
17315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17322f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
1733ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        int32_t numChannels = 0, sampleRate = 0, compressionLevel = -1;
17342f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (encoder &&
17352f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                (!msg->findInt32("channel-count", &numChannels)
17362f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                        || !msg->findInt32("sample-rate", &sampleRate))) {
17372f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("missing channel count or sample rate for FLAC encoder");
17382f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            err = INVALID_OPERATION;
17392f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        } else {
17402f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            if (encoder) {
1741516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                if (!msg->findInt32(
1742cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                            "complexity", &compressionLevel) &&
1743cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                    !msg->findInt32(
1744516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                            "flac-compression-level", &compressionLevel)) {
1745cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                    compressionLevel = 5; // default FLAC compression level
17462f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel < 0) {
1747516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1748516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 0",
1749516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
17502f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 0;
17512f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel > 8) {
1752516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1753516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 8",
1754516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
17552f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 8;
17562f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                }
17572f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            }
1758516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            err = setupFlacCodec(
1759516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    encoder, numChannels, sampleRate, compressionLevel);
17602f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
1761ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
1762ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        int32_t numChannels, sampleRate;
1763ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        if (encoder
1764ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("channel-count", &numChannels)
1765ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
1766ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = INVALID_OPERATION;
1767ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        } else {
1768ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
1769ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        }
177097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AC3)) {
177197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t numChannels;
177297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t sampleRate;
177397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        if (!msg->findInt32("channel-count", &numChannels)
177497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                || !msg->findInt32("sample-rate", &sampleRate)) {
177597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = INVALID_OPERATION;
177697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        } else {
177797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = setupAC3Codec(encoder, numChannels, sampleRate);
177897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        }
17798a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_EAC3)) {
17808a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        int32_t numChannels;
17818a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        int32_t sampleRate;
17828a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        if (!msg->findInt32("channel-count", &numChannels)
17838a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                || !msg->findInt32("sample-rate", &sampleRate)) {
17848a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            err = INVALID_OPERATION;
17858a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        } else {
17868a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            err = setupEAC3Codec(encoder, numChannels, sampleRate);
17878a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        }
17885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1789729de186450f78c099637e1fce743fe531862c52Andreas Huber
17904471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    if (err != OK) {
17914471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber        return err;
17924471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    }
17934471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber
17948b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
17958b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderDelay = 0;
17968b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
17979806555d3930be43e11106281dee354820ac1c88Andreas Huber
17988b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
17998b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderPadding = 0;
18008b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
18018b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen
18029806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (msg->findInt32("channel-mask", &mChannelMask)) {
18039806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = true;
18049806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else {
18059806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = false;
18069806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
18079806555d3930be43e11106281dee354820ac1c88Andreas Huber
1808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t maxInputSize;
1809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (msg->findInt32("max-input-size", &maxInputSize)) {
18105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
1811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
18125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
1813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
18145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18158b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    int32_t priority;
18168b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    if (msg->findInt32("priority", &priority)) {
18178b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu        err = setPriority(priority);
18188b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    }
18198b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu
1820ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    int32_t rateInt = -1;
1821ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    float rateFloat = -1;
1822ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (!msg->findFloat("operating-rate", &rateFloat)) {
1823ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        msg->findInt32("operating-rate", &rateInt);
1824ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        rateFloat = (float)rateInt;  // 16MHz (FLINTMAX) is OK for upper bound.
1825ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
1826ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (rateFloat > 0) {
1827ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        err = setOperatingRate(rateFloat, video);
1828ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
1829ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu
18304e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    mBaseOutputFormat = outputFormat;
18314e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar
1832e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ(getPortFormat(kPortIndexInput, inputFormat), (status_t)OK);
1833e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ(getPortFormat(kPortIndexOutput, outputFormat), (status_t)OK);
1834e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mInputFormat = inputFormat;
1835e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mOutputFormat = outputFormat;
1836e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
18375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
1838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
18408b806ea894ca098366629458bfdd1df4866afcdfRonghua Wustatus_t ACodec::setPriority(int32_t priority) {
18418b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    if (priority < 0) {
18428b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu        return BAD_VALUE;
18438b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    }
18448b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    OMX_PARAM_U32TYPE config;
18458b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    InitOMXParams(&config);
18468b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    config.nU32 = (OMX_U32)priority;
18478b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    status_t temp = mOMX->setConfig(
18488b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu            mNode, (OMX_INDEXTYPE)OMX_IndexConfigPriority,
18498b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu            &config, sizeof(config));
18508b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    if (temp != OK) {
18518b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu        ALOGI("codec does not support config priority (err %d)", temp);
18528b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    }
18538b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    return OK;
18548b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu}
18558b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu
1856ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wustatus_t ACodec::setOperatingRate(float rateFloat, bool isVideo) {
1857ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (rateFloat < 0) {
1858ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        return BAD_VALUE;
1859ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
1860ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    OMX_U32 rate;
1861ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (isVideo) {
1862ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        if (rateFloat > 65535) {
1863ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            return BAD_VALUE;
1864ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        }
1865ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        rate = (OMX_U32)(rateFloat * 65536.0f + 0.5f);
1866ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    } else {
1867ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        if (rateFloat > UINT_MAX) {
1868ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            return BAD_VALUE;
1869ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        }
1870ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        rate = (OMX_U32)(rateFloat);
1871ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
1872ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    OMX_PARAM_U32TYPE config;
1873ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    InitOMXParams(&config);
1874ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    config.nU32 = rate;
1875ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    status_t err = mOMX->setConfig(
1876ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            mNode, (OMX_INDEXTYPE)OMX_IndexConfigOperatingRate,
1877ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            &config, sizeof(config));
1878ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (err != OK) {
1879ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        ALOGI("codec does not support config operating rate (err %d)", err);
1880ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
1881ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    return OK;
1882ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu}
1883ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu
1884f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
1885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
1887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
1888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (def.nBufferSize >= size) {
1897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
1898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nBufferSize = size;
1901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
1903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->getParameter(
1910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(def.nBufferSize >= size);
1917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
19215778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::selectAudioPortFormat(
19225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
19235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_AUDIO_PARAM_PORTFORMATTYPE format;
19245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&format);
19255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    format.nPortIndex = portIndex;
19275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (OMX_U32 index = 0;; ++index) {
19285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        format.nIndex = index;
19295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
19315778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioPortFormat,
19325778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &format, sizeof(format));
19335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
19355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
19365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (format.eEncoding == desiredFormat) {
19395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
19445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format));
19455778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
19465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19475778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAACCodec(
1948aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        bool encoder, int32_t numChannels, int32_t sampleRate,
19498045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        int32_t bitRate, int32_t aacProfile, bool isADTS, int32_t sbrMode,
19502965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang        int32_t maxOutputChannelCount, const drcParams_t& drc,
19512965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang        int32_t pcmLimiterEnable) {
1952ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (encoder && isADTS) {
1953ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return -EINVAL;
1954ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
1955ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
19565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setupRawAudioFormat(
19575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
19585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sampleRate,
19595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            numChannels);
19605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (encoder) {
19665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
19675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
19695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
19705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
19735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
19745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = kPortIndexOutput;
19755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
19775778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
19785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
19805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
19815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.bFlagErrorConcealment = OMX_TRUE;
19845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
19855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
19875778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
19885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
19905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
19915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
19945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&profile);
19955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nPortIndex = kPortIndexOutput;
19965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
19985778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
19995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
20015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
20025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nChannels = numChannels;
20055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eChannelMode =
20075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (numChannels == 1)
20085778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
20095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nSampleRate = sampleRate;
20115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nBitRate = bitRate;
20125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAudioBandWidth = 0;
20135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nFrameLength = 0;
20145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACtools = OMX_AUDIO_AACToolAll;
20155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACERtools = OMX_AUDIO_AACERNone;
2016aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
20175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
2018b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        switch (sbrMode) {
2019b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 0:
2020b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // disable sbr
2021b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
2022b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
2023b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2024b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 1:
2025b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable single-rate sbr
2026b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
2027b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
2028b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2029b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 2:
2030b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable dual-rate sbr
2031b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
2032b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
2033b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2034b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case -1:
2035b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable both modes -> the codec will decide which mode should be used
2036b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
2037b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
2038b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2039b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        default:
2040b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // unsupported sbr mode
2041b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            return BAD_VALUE;
2042b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        }
2043b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi
20445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
20465778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
20475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
20495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
20505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_AUDIO_PARAM_AACPROFILETYPE profile;
2056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&profile);
2057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nPortIndex = kPortIndexInput;
2058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
20595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
2060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
2061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nChannels = numChannels;
2067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nSampleRate = sampleRate;
2068ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2069ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    profile.eAACStreamFormat =
2070ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        isADTS
2071ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            ? OMX_AUDIO_AACStreamFormatMP4ADTS
2072ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            : OMX_AUDIO_AACStreamFormatMP4FF;
2073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
20748045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    OMX_AUDIO_PARAM_ANDROID_AACPRESENTATIONTYPE presentation;
20758045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nMaxOutputChannels = maxOutputChannelCount;
20768045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nDrcCut = drc.drcCut;
20778045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nDrcBoost = drc.drcBoost;
20788045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nHeavyCompression = drc.heavyCompression;
20798045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nTargetReferenceLevel = drc.targetRefLevel;
20808045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nEncodedTargetLevel = drc.encodedTargetLevel;
20812965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang    presentation.nPCMLimiterEnable = pcmLimiterEnable;
20828045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi
20838045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    status_t res = mOMX->setParameter(mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
20848045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    if (res == OK) {
20858045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        // optional parameters, will not cause configuration failure
20868045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        mOMX->setParameter(mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAacPresentation,
20878045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                &presentation, sizeof(presentation));
20888045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    } else {
20898045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        ALOGW("did not set AudioAndroidAacPresentation due to error %d when setting AudioAac", res);
20908045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    }
20918045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    return res;
20925778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
2093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
209497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryustatus_t ACodec::setupAC3Codec(
209597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        bool encoder, int32_t numChannels, int32_t sampleRate) {
209697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    status_t err = setupRawAudioFormat(
209797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
209897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
209997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
210097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
210197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
210297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
210397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (encoder) {
210497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        ALOGW("AC3 encoding is not supported.");
210597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return INVALID_OPERATION;
210697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
210797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
210897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    OMX_AUDIO_PARAM_ANDROID_AC3TYPE def;
210997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    InitOMXParams(&def);
211097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nPortIndex = kPortIndexInput;
211197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
211297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    err = mOMX->getParameter(
211397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
211497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
211597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
211697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
211797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
211897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
211997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
212097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
212197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
212297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nChannels = numChannels;
212397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nSampleRate = sampleRate;
212497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
212597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    return mOMX->setParameter(
212697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
212797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
212897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
212997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
213097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu}
213197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
21328a4728966dc9c78e21c3c93a927707e93c05e5e0Rachadstatus_t ACodec::setupEAC3Codec(
21338a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        bool encoder, int32_t numChannels, int32_t sampleRate) {
21348a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    status_t err = setupRawAudioFormat(
21358a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
21368a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
21378a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (err != OK) {
21388a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return err;
21398a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
21408a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
21418a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (encoder) {
21428a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        ALOGW("EAC3 encoding is not supported.");
21438a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return INVALID_OPERATION;
21448a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
21458a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
21468a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    OMX_AUDIO_PARAM_ANDROID_EAC3TYPE def;
21478a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    InitOMXParams(&def);
21488a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nPortIndex = kPortIndexInput;
21498a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
21508a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    err = mOMX->getParameter(
21518a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            mNode,
21528a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
21538a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            &def,
21548a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            sizeof(def));
21558a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
21568a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (err != OK) {
21578a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return err;
21588a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
21598a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
21608a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nChannels = numChannels;
21618a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nSampleRate = sampleRate;
21628a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
21638a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    return mOMX->setParameter(
21648a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            mNode,
21658a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
21668a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            &def,
21678a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            sizeof(def));
21688a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad}
21698a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
21705778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
21715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        bool isAMRWB, int32_t bps) {
21725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (isAMRWB) {
21735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 6600) {
21745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB0;
21755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 8850) {
21765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB1;
21775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 12650) {
21785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB2;
21795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 14250) {
21805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB3;
21815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 15850) {
21825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB4;
21835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 18250) {
21845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB5;
21855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 19850) {
21865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB6;
21875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 23050) {
21885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB7;
21895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 23850 bps
21925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeWB8;
21935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {  // AMRNB
21945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 4750) {
21955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB0;
21965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5150) {
21975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB1;
21985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5900) {
21995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB2;
22005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 6700) {
22015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB3;
22025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7400) {
22035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB4;
22045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7950) {
22055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB5;
22065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 10200) {
22075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB6;
22085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 12200 bps
22115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeNB7;
22125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
22155778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
2216729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_AMRTYPE def;
2217729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
22185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
2219729de186450f78c099637e1fce743fe531862c52Andreas Huber
2220729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err =
2221729de186450f78c099637e1fce743fe531862c52Andreas Huber        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
2222729de186450f78c099637e1fce743fe531862c52Andreas Huber
2223729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2224729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2225729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2226729de186450f78c099637e1fce743fe531862c52Andreas Huber
2227729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
22285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
22295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
22315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
2232729de186450f78c099637e1fce743fe531862c52Andreas Huber
22335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2236729de186450f78c099637e1fce743fe531862c52Andreas Huber
22375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupRawAudioFormat(
22385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
22395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            isWAMR ? 16000 : 8000 /* sampleRate */,
22405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            1 /* numChannels */);
2241729de186450f78c099637e1fce743fe531862c52Andreas Huber}
2242729de186450f78c099637e1fce743fe531862c52Andreas Huber
224317c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissenstatus_t ACodec::setupG711Codec(bool encoder, int32_t sampleRate, int32_t numChannels) {
22445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(!encoder);  // XXX TODO
22455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2246729de186450f78c099637e1fce743fe531862c52Andreas Huber    return setupRawAudioFormat(
224717c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            kPortIndexInput, sampleRate, numChannels);
2248729de186450f78c099637e1fce743fe531862c52Andreas Huber}
2249729de186450f78c099637e1fce743fe531862c52Andreas Huber
22502f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivistatus_t ACodec::setupFlacCodec(
22512f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
22522f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
22532f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder) {
22542f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        OMX_AUDIO_PARAM_FLACTYPE def;
22552f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        InitOMXParams(&def);
22562f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nPortIndex = kPortIndexOutput;
22572f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
22582f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        // configure compression level
22592f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        status_t err = mOMX->getParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
22602f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
22612f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
22622f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
22632f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
22642f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nCompressionLevel = compressionLevel;
22652f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        err = mOMX->setParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
22662f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
22672f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
22682f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
22692f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
22702f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
22712f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
22722f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    return setupRawAudioFormat(
22732f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            encoder ? kPortIndexInput : kPortIndexOutput,
22742f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            sampleRate,
22752f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            numChannels);
22762f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi}
22772f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
2278729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t ACodec::setupRawAudioFormat(
2279729de186450f78c099637e1fce743fe531862c52Andreas Huber        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
2280729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
2281729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
2282729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.nPortIndex = portIndex;
2283729de186450f78c099637e1fce743fe531862c52Andreas Huber
2284729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err = mOMX->getParameter(
2285729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2286729de186450f78c099637e1fce743fe531862c52Andreas Huber
2287729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2288729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2289729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2290729de186450f78c099637e1fce743fe531862c52Andreas Huber
2291729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
2292729de186450f78c099637e1fce743fe531862c52Andreas Huber
2293729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->setParameter(
2294729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2295729de186450f78c099637e1fce743fe531862c52Andreas Huber
2296729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2297729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2298729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2299729de186450f78c099637e1fce743fe531862c52Andreas Huber
2300729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
2301729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&pcmParams);
2302729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nPortIndex = portIndex;
2303729de186450f78c099637e1fce743fe531862c52Andreas Huber
2304729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->getParameter(
2305729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
2306729de186450f78c099637e1fce743fe531862c52Andreas Huber
2307729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2308729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2309729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2310729de186450f78c099637e1fce743fe531862c52Andreas Huber
2311729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nChannels = numChannels;
2312729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.eNumData = OMX_NumericalDataSigned;
2313729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.bInterleaved = OMX_TRUE;
2314729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nBitPerSample = 16;
2315729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nSamplingRate = sampleRate;
2316729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
2317729de186450f78c099637e1fce743fe531862c52Andreas Huber
2318c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber    if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
2319c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber        return OMX_ErrorNone;
2320729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2321729de186450f78c099637e1fce743fe531862c52Andreas Huber
2322729de186450f78c099637e1fce743fe531862c52Andreas Huber    return mOMX->setParameter(
2323729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
2324729de186450f78c099637e1fce743fe531862c52Andreas Huber}
2325729de186450f78c099637e1fce743fe531862c52Andreas Huber
23265a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachadstatus_t ACodec::configureTunneledVideoPlayback(
232797827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad        int32_t audioHwSync, const sp<ANativeWindow> &nativeWindow) {
23285a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    native_handle_t* sidebandHandle;
23295a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
23305a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    status_t err = mOMX->configureVideoTunnelMode(
23315a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            mNode, kPortIndexOutput, OMX_TRUE, audioHwSync, &sidebandHandle);
23325a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    if (err != OK) {
23335a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        ALOGE("configureVideoTunnelMode failed! (err %d).", err);
23345a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        return err;
23355a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    }
23365a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
23375a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    err = native_window_set_sideband_stream(nativeWindow.get(), sidebandHandle);
23385a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    if (err != OK) {
23395a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        ALOGE("native_window_set_sideband_stream(%p) failed! (err %d).",
23405a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                sidebandHandle, err);
23415a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        return err;
23425a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    }
23435a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
23445a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    return OK;
23455a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad}
23465a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
2347f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoPortFormatType(
2348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
2349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_VIDEO_CODINGTYPE compressionFormat,
23500d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        OMX_COLOR_FORMATTYPE colorFormat,
23510d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        bool usingNativeBuffers) {
2352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
2353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
2354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = portIndex;
2355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
2356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool found = false;
2357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 index = 0;
2359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (;;) {
2360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        format.nIndex = index;
2361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->getParameter(
2362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamVideoPortFormat,
2363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &format, sizeof(format));
2364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
2366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return err;
2367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2369229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        // substitute back flexible color format to codec supported format
2370229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        OMX_U32 flexibleEquivalent;
23710d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (compressionFormat == OMX_VIDEO_CodingUnused
23720d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && isFlexibleColorFormat(
23730d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        mOMX, mNode, format.eColorFormat, usingNativeBuffers, &flexibleEquivalent)
23740d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && colorFormat == flexibleEquivalent) {
2375229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            ALOGI("[%s] using color format %#x in place of %#x",
2376229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                    mComponentName.c_str(), format.eColorFormat, colorFormat);
2377229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            colorFormat = format.eColorFormat;
2378229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
2379229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
2380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The following assertion is violated by TI's video decoder.
2381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // CHECK_EQ(format.nIndex, index);
2382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
2384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexInput
2385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && colorFormat == format.eColorFormat) {
2386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eCompressionFormat does not seem right.
2387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
2388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
2389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexOutput
2391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && compressionFormat == format.eCompressionFormat) {
2392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eColorFormat does not seem right.
2393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
2394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
2395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (format.eCompressionFormat == compressionFormat
2399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && format.eColorFormat == colorFormat) {
2400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            found = true;
2401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ++index;
2405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!found) {
2408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return UNKNOWN_ERROR;
2409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->setParameter(
2412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
2413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
2414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
2416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
24180d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// Set optimal output format. OMX component lists output formats in the order
24190d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// of preference, but this got more complicated since the introduction of flexible
24200d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// YUV formats. We support a legacy behavior for applications that do not use
24210d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// surface output, do not specify an output format, but expect a "usable" standard
24220d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// OMX format. SW readable and standard formats must be flex-YUV.
24230d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar//
24240d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// Suggested preference order:
24250d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal format for texture rendering (mediaplayer behavior)
24260d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal SW readable & texture renderable format (flex-YUV support)
24270d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal SW readable non-renderable format (flex-YUV bytebuffer support)
24280d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - legacy "usable" standard formats
24290d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar//
24300d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// For legacy support, we prefer a standard format, but will settle for a SW readable
24310d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// flex-YUV format.
24320d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnarstatus_t ACodec::setSupportedOutputFormat(bool getLegacyFlexibleFormat) {
24330d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    OMX_VIDEO_PARAM_PORTFORMATTYPE format, legacyFormat;
2434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
2435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = kPortIndexOutput;
2436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
24370d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    InitOMXParams(&legacyFormat);
24380d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    // this field will change when we find a suitable legacy format
24390d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    legacyFormat.eColorFormat = OMX_COLOR_FormatUnused;
2440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
24410d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    for (OMX_U32 index = 0; ; ++index) {
24420d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        format.nIndex = index;
24430d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        status_t err = mOMX->getParameter(
24440d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                mNode, OMX_IndexParamVideoPortFormat,
24450d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                &format, sizeof(format));
24460d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (err != OK) {
24470d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            // no more formats, pick legacy format if found
24480d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            if (legacyFormat.eColorFormat != OMX_COLOR_FormatUnused) {
24490d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                 memcpy(&format, &legacyFormat, sizeof(format));
24500d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                 break;
24510d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            }
24520d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            return err;
24530d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
24540d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (format.eCompressionFormat != OMX_VIDEO_CodingUnused) {
24550d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            return OMX_ErrorBadParameter;
24560d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
24570d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (!getLegacyFlexibleFormat) {
24580d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            break;
24590d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
24600d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        // standard formats that were exposed to users before
24610d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (format.eColorFormat == OMX_COLOR_FormatYUV420Planar
24620d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_COLOR_FormatYUV420PackedPlanar
24630d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar
24640d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_COLOR_FormatYUV420PackedSemiPlanar
24650d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar) {
24660d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            break;
24670d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
24680d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        // find best legacy non-standard format
24690d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        OMX_U32 flexibleEquivalent;
24700d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (legacyFormat.eColorFormat == OMX_COLOR_FormatUnused
24710d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && isFlexibleColorFormat(
24720d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        mOMX, mNode, format.eColorFormat, false /* usingNativeBuffers */,
24730d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        &flexibleEquivalent)
24740d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && flexibleEquivalent == OMX_COLOR_FormatYUV420Flexible) {
24750d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            memcpy(&legacyFormat, &format, sizeof(format));
24760d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
24770d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    }
2478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mOMX->setParameter(
2479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
2480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
2481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2483e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic const struct VideoCodingMapEntry {
2484e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    const char *mMime;
2485e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    OMX_VIDEO_CODINGTYPE mVideoCodingType;
2486e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber} kVideoCodingMapEntry[] = {
2487e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC },
24882472b1c0d63454e5d90a982bd6c555de6c3127bdRachad    { MEDIA_MIMETYPE_VIDEO_HEVC, OMX_VIDEO_CodingHEVC },
2489e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 },
2490e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 },
2491e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 },
249294705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 },
249394705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 },
2494e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber};
2495e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
24965778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic status_t GetVideoCodingTypeFromMime(
24975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
2498e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
2499e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
2500e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
2501e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) {
2502e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *codingType = kVideoCodingMapEntry[i].mVideoCodingType;
2503e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
2504e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
2505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2507e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    *codingType = OMX_VIDEO_CodingUnused;
2508e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2509e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
2510e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
2511e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2512e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic status_t GetMimeTypeForVideoCoding(
2513e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        OMX_VIDEO_CODINGTYPE codingType, AString *mime) {
2514e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
2515e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
2516e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
2517e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) {
2518e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *mime = kVideoCodingMapEntry[i].mMime;
2519e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
2520e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
2521e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
2522e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2523e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    mime->clear();
2524e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2525e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
25265778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
25275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25285778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoDecoder(
25290d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        const char *mime, const sp<AMessage> &msg, bool haveNativeWindow) {
253089869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    int32_t width, height;
253189869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    if (!msg->findInt32("width", &width)
253289869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            || !msg->findInt32("height", &height)) {
253389869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        return INVALID_OPERATION;
253489869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    }
253589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar
25365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
25375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
25385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
25405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
25415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
2544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
2545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
255089869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    int32_t tmp;
255189869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    if (msg->findInt32("color-format", &tmp)) {
255289869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        OMX_COLOR_FORMATTYPE colorFormat =
255389869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            static_cast<OMX_COLOR_FORMATTYPE>(tmp);
255489869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        err = setVideoPortFormatType(
25550d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                kPortIndexOutput, OMX_VIDEO_CodingUnused, colorFormat, haveNativeWindow);
255689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        if (err != OK) {
255789869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            ALOGW("[%s] does not support color format %d",
255889869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar                  mComponentName.c_str(), colorFormat);
25590d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            err = setSupportedOutputFormat(!haveNativeWindow /* getLegacyFlexibleFormat */);
256089869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        }
256189869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    } else {
25620d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        err = setSupportedOutputFormat(!haveNativeWindow /* getLegacyFlexibleFormat */);
256389869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    }
2564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
256978b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    int32_t frameRateInt;
257078b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    float frameRateFloat;
257178b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    if (!msg->findFloat("frame-rate", &frameRateFloat)) {
257278b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        if (!msg->findInt32("frame-rate", &frameRateInt)) {
257378b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            frameRateInt = -1;
257478b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        }
257578b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        frameRateFloat = (float)frameRateInt;
257678b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    }
257778b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad
2578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
257978b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            kPortIndexInput, width, height, compressionFormat, frameRateFloat);
2580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
2586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
2587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
25955778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) {
25965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
25975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("color-format", &tmp)) {
25985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
25995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_COLOR_FORMATTYPE colorFormat =
26025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        static_cast<OMX_COLOR_FORMATTYPE>(tmp);
26035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setVideoPortFormatType(
26055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
26065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
26085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support color format %d",
26095778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str(), colorFormat);
26105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
26125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Input port configuration */
26155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
26175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&def);
26185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
26205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexInput;
26225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
26245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
26255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
26275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
26285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t width, height, bitrate;
26315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("width", &width)
26325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("height", &height)
26335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("bitrate", &bitrate)) {
26345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
26355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
26385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
26395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t stride;
26415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("stride", &stride)) {
26425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        stride = width;
26435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nStride = stride;
26465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t sliceHeight;
26485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("slice-height", &sliceHeight)) {
26495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sliceHeight = height;
26505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nSliceHeight = sliceHeight;
26535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
26555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
26575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
26585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
26595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
26605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
26615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
26625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
26632c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        mTimePerFrameUs = (int64_t) (1000000.0f / frameRate);
26645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
26675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
2668a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    // this is redundant as it was already set up in setVideoPortFormatType
2669a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    // FIXME for now skip this only for flexible YUV formats
2670a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    if (colorFormat != OMX_COLOR_FormatYUV420Flexible) {
2671a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar        video_def->eColorFormat = colorFormat;
2672a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    }
26735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
26755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
26765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
26785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set input port definition parameters.",
26795778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
26805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
26825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Output port configuration */
26855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
26875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
26885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
26905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
26915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
26945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
26955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
26975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support compression format %d",
26985778822d86b0337407514b9372562b86edfa91cdAndreas Huber             mComponentName.c_str(), compressionFormat);
26995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
27015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexOutput;
27045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
27065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
27075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
27095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
27105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
27135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
27145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = 0;
27155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nBitrate = bitrate;
27165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = compressionFormat;
27175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = OMX_COLOR_FormatUnused;
27185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
27205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
27215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
27235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set output port definition parameters.",
27245778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
27255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
27275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (compressionFormat) {
27305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingMPEG4:
27315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupMPEG4EncoderParameters(msg);
27325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
27335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingH263:
27355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupH263EncoderParameters(msg);
27365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
27375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingAVC:
27395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupAVCEncoderParameters(msg);
27405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
27415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2742c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        case OMX_VIDEO_CodingHEVC:
2743c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            err = setupHEVCEncoderParameters(msg);
2744c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            break;
2745c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
274689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP8:
274789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP9:
274889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            err = setupVPXEncoderParameters(msg);
274989b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            break;
275089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
27515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
27525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
27535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGI("setupVideoEncoder succeeded");
27565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
27585778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
27595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27600dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dongstatus_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) {
27610dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    OMX_VIDEO_PARAM_INTRAREFRESHTYPE params;
27620dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    InitOMXParams(&params);
27630dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.nPortIndex = kPortIndexOutput;
27640dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
27650dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode);
27660dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
27670dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic ||
27680dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
27690dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
27700dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) {
27710dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
27720dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
27730dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nCirMBs = mbs;
27740dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
27750dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
27760dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive ||
27770dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
27780dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
27790dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) {
27800dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
27810dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
27820dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirMBs = mbs;
27830dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
27840dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t ref;
27850dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) {
27860dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
27870dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
27880dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirRef = ref;
27890dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
27900dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
27910dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = mOMX->setParameter(
27920dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            mNode, OMX_IndexParamVideoIntraRefresh,
27930dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            &params, sizeof(params));
27940dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    return err;
27950dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong}
27960dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
27975778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
27985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (iFramesInterval < 0) {
27995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0xFFFFFFFF;
28005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (iFramesInterval == 0) {
28015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0;
28025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_U32 ret = frameRate * iFramesInterval;
28045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return ret;
28055778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
28065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
280796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatic OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) {
280896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    int32_t tmp;
280996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    if (!msg->findInt32("bitrate-mode", &tmp)) {
281096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        return OMX_Video_ControlRateVariable;
281196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    }
281296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
281396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp);
281496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber}
281596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
28165778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
28175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
28185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
28195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
28205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
28215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
282396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
282496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
28255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
28265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
28275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
28285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
28295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
28305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
28315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
28325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
28355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&mpeg4type);
28365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPortIndex = kPortIndexOutput;
28375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
28395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
28405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
28425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
28435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nSliceHeaderSpacing = 0;
28465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bSVH = OMX_FALSE;
28475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bGov = OMX_FALSE;
28485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nAllowedPictureTypes =
28505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
28515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
28535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mpeg4type.nPFrames == 0) {
28545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
28555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nBFrames = 0;
28575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nIDCVLCThreshold = 0;
28585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bACPred = OMX_TRUE;
28595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nMaxPacketSize = 256;
28605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nTimeIncRes = 1000;
28615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nHeaderExtension = 0;
28625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bReversibleVLC = OMX_FALSE;
28635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
28655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
28665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
28675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
28685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
28695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
28705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
28725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
28745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
28755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
28765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
28785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
28795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
28825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
28835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
28855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
28865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
288896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
28895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
28915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
28925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
28955778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
28965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28975778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
28985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
28995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
29005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
29015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
29025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
290496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
290596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
29065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
29075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
29085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
29095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
29105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
29115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
29125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
29135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_H263TYPE h263type;
29165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h263type);
29175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPortIndex = kPortIndexOutput;
29185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
29205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
29215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
29235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
29245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nAllowedPictureTypes =
29275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
29285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
29305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h263type.nPFrames == 0) {
29315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
29325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nBFrames = 0;
29345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
29365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
29375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
29385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
29395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
29405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
29415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
29435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
29455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
29465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
29475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
29495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
29505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bPLUSPTYPEAllowed = OMX_FALSE;
29535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bForceRoundingTypeToZero = OMX_FALSE;
29545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPictureHeaderRepetition = 0;
29555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nGOBHeaderInterval = 0;
29565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
29585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
29595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
29615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
29625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
296496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
29655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
29675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
29685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
29715778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
29725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2973a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar// static
2974a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnarint /* OMX_VIDEO_AVCLEVELTYPE */ ACodec::getAVCLevelFor(
2975a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        int width, int height, int rate, int bitrate,
2976a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        OMX_VIDEO_AVCPROFILETYPE profile) {
2977a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    // convert bitrate to main/baseline profile kbps equivalent
2978a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    switch (profile) {
2979a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        case OMX_VIDEO_AVCProfileHigh10:
2980a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 3000); break;
2981a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        case OMX_VIDEO_AVCProfileHigh:
2982a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 1250); break;
2983a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        default:
2984a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 1000); break;
2985a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    }
2986a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
2987a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    // convert size and rate to MBs
2988a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    width = divUp(width, 16);
2989a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    height = divUp(height, 16);
2990a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    int mbs = width * height;
2991a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    rate *= mbs;
2992a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    int maxDimension = max(width, height);
2993a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
2994a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    static const int limits[][5] = {
2995a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        /*   MBps     MB   dim  bitrate        level */
2996a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    1485,    99,  28,     64, OMX_VIDEO_AVCLevel1  },
2997a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    1485,    99,  28,    128, OMX_VIDEO_AVCLevel1b },
2998a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    3000,   396,  56,    192, OMX_VIDEO_AVCLevel11 },
2999a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    6000,   396,  56,    384, OMX_VIDEO_AVCLevel12 },
3000a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   11880,   396,  56,    768, OMX_VIDEO_AVCLevel13 },
3001a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   11880,   396,  56,   2000, OMX_VIDEO_AVCLevel2  },
3002a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   19800,   792,  79,   4000, OMX_VIDEO_AVCLevel21 },
3003a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   20250,  1620, 113,   4000, OMX_VIDEO_AVCLevel22 },
3004a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   40500,  1620, 113,  10000, OMX_VIDEO_AVCLevel3  },
3005a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  108000,  3600, 169,  14000, OMX_VIDEO_AVCLevel31 },
3006a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  216000,  5120, 202,  20000, OMX_VIDEO_AVCLevel32 },
3007a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  245760,  8192, 256,  20000, OMX_VIDEO_AVCLevel4  },
3008a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  245760,  8192, 256,  50000, OMX_VIDEO_AVCLevel41 },
3009a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  522240,  8704, 263,  50000, OMX_VIDEO_AVCLevel42 },
3010a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  589824, 22080, 420, 135000, OMX_VIDEO_AVCLevel5  },
3011a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  983040, 36864, 543, 240000, OMX_VIDEO_AVCLevel51 },
3012a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        { 2073600, 36864, 543, 240000, OMX_VIDEO_AVCLevel52 },
3013a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    };
3014a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
3015a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    for (size_t i = 0; i < ARRAY_SIZE(limits); i++) {
3016a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        const int (&limit)[5] = limits[i];
3017a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        if (rate <= limit[0] && mbs <= limit[1] && maxDimension <= limit[2]
3018a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar                && bitrate <= limit[3]) {
3019a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            return limit[4];
3020a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        }
3021a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    }
3022a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    return 0;
3023a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar}
3024a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
30255778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
30265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
30275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
30285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
30295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
30305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
30315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
303296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
303396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
30345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
30355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
30365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
30375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
30385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
30395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
30405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
30415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
30425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30430dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = OK;
30440dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    int32_t intraRefreshMode = 0;
30450dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) {
30460dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode);
30470dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (err != OK) {
30480dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
30490dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong                    err, intraRefreshMode);
30500dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return err;
30510dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
30520dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
30530dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
30545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_AVCTYPE h264type;
30555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h264type);
30565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nPortIndex = kPortIndexOutput;
30575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30580dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    err = mOMX->getParameter(
30595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
30605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
30625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
30635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
30645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nAllowedPictureTypes =
30665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
30675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
30695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
30705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
30715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
30725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
30735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
30745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
30765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
30785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
30795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
30805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
30825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
30835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
30845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // XXX
30867c25df82dfc8bbedb58608242f0d923a4594bb14James Dong    if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) {
30877c25df82dfc8bbedb58608242f0d923a4594bb14James Dong        ALOGW("Use baseline profile instead of %d for AVC recording",
30887c25df82dfc8bbedb58608242f0d923a4594bb14James Dong            h264type.eProfile);
30895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
30905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
30915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
30935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nSliceHeaderSpacing = 0;
30945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bUseHadamard = OMX_TRUE;
30955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefFrames = 1;
30965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nBFrames = 0;
30975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
30985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (h264type.nPFrames == 0) {
30995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
31005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
31015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx10ActiveMinus1 = 0;
31025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx11ActiveMinus1 = 0;
31035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bEntropyCodingCABAC = OMX_FALSE;
31045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bWeightedPPrediction = OMX_FALSE;
31055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bconstIpred = OMX_FALSE;
31065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirect8x8Inference = OMX_FALSE;
31075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirectSpatialTemporal = OMX_FALSE;
31085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nCabacInitIdc = 0;
31095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
31105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.nBFrames != 0) {
31125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
31135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
31145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableUEP = OMX_FALSE;
31165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableFMO = OMX_FALSE;
31175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableASO = OMX_FALSE;
31185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableRS = OMX_FALSE;
31195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bFrameMBsOnly = OMX_TRUE;
31205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bMBAFF = OMX_FALSE;
31215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
31225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
31245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
31255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
31275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
31285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
31295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
313096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return configureBitrate(bitrate, bitrateMode);
31315778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
31325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3133c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachadstatus_t ACodec::setupHEVCEncoderParameters(const sp<AMessage> &msg) {
3134c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    int32_t bitrate, iFrameInterval;
3135c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findInt32("bitrate", &bitrate)
3136c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
3137c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return INVALID_OPERATION;
3138c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
3139c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3140c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
3141c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3142c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    float frameRate;
3143c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findFloat("frame-rate", &frameRate)) {
3144c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t tmp;
3145c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("frame-rate", &tmp)) {
3146c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
3147c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
3148c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        frameRate = (float)tmp;
3149c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
3150c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3151c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_PARAM_HEVCTYPE hevcType;
3152c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    InitOMXParams(&hevcType);
3153c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    hevcType.nPortIndex = kPortIndexOutput;
3154c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3155c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    status_t err = OK;
3156c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    err = mOMX->getParameter(
3157c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
3158c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
3159c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
3160c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
3161c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3162c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    int32_t profile;
3163c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (msg->findInt32("profile", &profile)) {
3164c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t level;
3165c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("level", &level)) {
3166c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
3167c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
3168c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3169c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        err = verifySupportForProfileAndLevel(profile, level);
3170c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (err != OK) {
3171c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return err;
3172c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
3173c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3174c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eProfile = static_cast<OMX_VIDEO_HEVCPROFILETYPE>(profile);
3175c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eLevel = static_cast<OMX_VIDEO_HEVCLEVELTYPE>(level);
3176c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
3177c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3178c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    // TODO: Need OMX structure definition for setting iFrameInterval
3179c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3180c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    err = mOMX->setParameter(
3181c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
3182c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
3183c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
3184c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
3185c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3186c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    return configureBitrate(bitrate, bitrateMode);
3187c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad}
3188c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
318989b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huberstatus_t ACodec::setupVPXEncoderParameters(const sp<AMessage> &msg) {
319089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    int32_t bitrate;
31914154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    int32_t iFrameInterval = 0;
31924154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    size_t tsLayers = 0;
31934154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE pattern =
31944154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        OMX_VIDEO_VPXTemporalLayerPatternNone;
31954154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    static const uint32_t kVp8LayerRateAlloction
31964154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS]
31974154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS] = {
31984154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        {100, 100, 100},  // 1 layer
31994154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 60, 100, 100},  // 2 layers {60%, 40%}
32004154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 40,  60, 100},  // 3 layers {40%, 20%, 40%}
32014154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    };
320289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    if (!msg->findInt32("bitrate", &bitrate)) {
320389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        return INVALID_OPERATION;
320489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    }
32054154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    msg->findInt32("i-frame-interval", &iFrameInterval);
320689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
320789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
320889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
32094154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    float frameRate;
32104154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (!msg->findFloat("frame-rate", &frameRate)) {
32114154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        int32_t tmp;
32124154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (!msg->findInt32("frame-rate", &tmp)) {
32134154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            return INVALID_OPERATION;
32144154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
32154154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        frameRate = (float)tmp;
32164154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
32174154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
32184154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    AString tsSchema;
32194154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (msg->findString("ts-schema", &tsSchema)) {
32204154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (tsSchema == "webrtc.vp8.1-layer") {
32214154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
32224154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 1;
32234154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else if (tsSchema == "webrtc.vp8.2-layer") {
32244154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
32254154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 2;
32264154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else if (tsSchema == "webrtc.vp8.3-layer") {
32274154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
32284154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 3;
32294154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else {
32304154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            ALOGW("Unsupported ts-schema [%s]", tsSchema.c_str());
32314154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
32324154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
32334154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
32344154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
32354154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    InitOMXParams(&vp8type);
32364154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    vp8type.nPortIndex = kPortIndexOutput;
32374154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    status_t err = mOMX->getParameter(
32384154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
32394154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            &vp8type, sizeof(vp8type));
32404154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
32414154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (err == OK) {
32424154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (iFrameInterval > 0) {
32434154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nKeyFrameInterval = setPFramesSpacing(iFrameInterval, frameRate);
32444154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
32454154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.eTemporalPattern = pattern;
32464154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.nTemporalLayerCount = tsLayers;
32474154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (tsLayers > 0) {
32484154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            for (size_t i = 0; i < OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS; i++) {
32494154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                vp8type.nTemporalLayerBitrateRatio[i] =
32504154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                    kVp8LayerRateAlloction[tsLayers - 1][i];
32514154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            }
32524154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
32534154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (bitrateMode == OMX_Video_ControlRateConstant) {
32544154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMinQuantizer = 2;
32554154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMaxQuantizer = 63;
32564154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
32574154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
32584154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        err = mOMX->setParameter(
32594154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
32604154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                &vp8type, sizeof(vp8type));
32614154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (err != OK) {
32624154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            ALOGW("Extended VP8 parameters set failed: %d", err);
32634154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
32644154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
32654154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
326689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    return configureBitrate(bitrate, bitrateMode);
326789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber}
326889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
32695778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::verifySupportForProfileAndLevel(
32705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t profile, int32_t level) {
32715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
32725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&params);
32735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    params.nPortIndex = kPortIndexOutput;
32745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (params.nProfileIndex = 0;; ++params.nProfileIndex) {
32765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
32775778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode,
32785778822d86b0337407514b9372562b86edfa91cdAndreas Huber                OMX_IndexParamVideoProfileLevelQuerySupported,
32795778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &params,
32805778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sizeof(params));
32815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
32835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
32845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
32855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
32875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
32885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (profile == supportedProfile && level <= supportedLevel) {
32905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OK;
32915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
32925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
32935778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
32945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
329596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatus_t ACodec::configureBitrate(
329696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) {
32975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
32985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&bitrateType);
32995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
33005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
33025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
33035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
33045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
33065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
33075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
33085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
330996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    bitrateType.eControlRate = bitrateMode;
33105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nTargetBitrate = bitrate;
33115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
33135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
33145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
33155778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
33165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33175778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupErrorCorrectionParameters() {
33185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
33195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&errorCorrectionType);
33205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nPortIndex = kPortIndexOutput;
33215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
33235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
33245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
33255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
33275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OK;  // Optional feature. Ignore this failure
33285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
33295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableHEC = OMX_FALSE;
33315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableResync = OMX_TRUE;
33325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nResynchMarkerSpacing = 256;
33335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
33345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableRVLC = OMX_FALSE;
33355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
33375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
33385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
33395778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
33405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3341f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoFormatOnPort(
3342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
334378b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat,
334478b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        float frameRate) {
3345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
3346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
3347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
3348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
3350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
3352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
3353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
3355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
3357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // XXX Need a (much) better heuristic to compute input buffer sizes.
3358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const size_t X = 64 * 1024;
3359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (def.nBufferSize < X) {
3360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.nBufferSize = X;
3361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
3365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameWidth = width;
3367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameHeight = height;
3368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
3370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eCompressionFormat = compressionFormat;
3371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eColorFormat = OMX_COLOR_FormatUnused;
337278b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        if (frameRate >= 0) {
337378b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
337478b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        }
3375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
3378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
3379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
3381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3383f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::initNativeWindow() {
3384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL) {
3385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
3386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
3389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
3390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3392d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Hubersize_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
3393d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    size_t n = 0;
3394d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
3395d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
3396d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        const BufferInfo &info = mBuffers[portIndex].itemAt(i);
3397d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
3398d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
3399d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            ++n;
3400d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        }
3401d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    }
3402d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
3403d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    return n;
3404d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber}
3405d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
34067e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubersize_t ACodec::countBuffersOwnedByNativeWindow() const {
34077e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    size_t n = 0;
34087e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
34097e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
34107e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
34117e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
34127e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
34137e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            ++n;
34147e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        }
34157e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
34167e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
34177e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    return n;
34187e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
34197e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
34207e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubervoid ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
34217e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (mNativeWindow == NULL) {
34227e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        return;
34237e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
34247e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
3425e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    while (countBuffersOwnedByNativeWindow() > mNumUndequeuedBuffers
34267e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            && dequeueBufferFromNativeWindow() != NULL) {
3427c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        // these buffers will be submitted as regular buffers; account for this
3428c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        if (mStoreMetaDataInOutputBuffers && mMetaDataBuffersToSubmit > 0) {
3429c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar            --mMetaDataBuffersToSubmit;
3430c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        }
34317e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
34327e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
34337e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
3434f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs(
3435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
3436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
3437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
3438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus != BufferInfo::OWNED_BY_US
3440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3441609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGV("[%s] Buffer %u on port %u still has status %d",
3442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mComponentName.c_str(),
3443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info->mBufferID, portIndex, info->mStatus);
3444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
3445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3451f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs() {
3452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return allYourBuffersAreBelongToUs(kPortIndexInput)
3453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        && allYourBuffersAreBelongToUs(kPortIndexOutput);
3454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3456f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::deferMessage(const sp<AMessage> &msg) {
3457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.push_back(msg);
3458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3460f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::processDeferredMessages() {
3461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> > queue = mDeferredQueue;
3462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.clear();
3463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> >::iterator it = queue.begin();
3465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while (it != queue.end()) {
3466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        onMessageReceived(*it++);
3467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
347003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar// static
3471229d242665c612fd97431d1e7ac004823b47f181Lajos Molnarbool ACodec::describeDefaultColorFormat(DescribeColorFormatParams &params) {
347203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    MediaImage &image = params.sMediaImage;
347303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    memset(&image, 0, sizeof(image));
347403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
347503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mType = MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
347603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mNumPlanes = 0;
347703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
347803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    const OMX_COLOR_FORMATTYPE fmt = params.eColorFormat;
347903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mWidth = params.nFrameWidth;
348003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mHeight = params.nFrameHeight;
348103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
348203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    // only supporting YUV420
348303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    if (fmt != OMX_COLOR_FormatYUV420Planar &&
348403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        fmt != OMX_COLOR_FormatYUV420PackedPlanar &&
348503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        fmt != OMX_COLOR_FormatYUV420SemiPlanar &&
34865a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        fmt != OMX_COLOR_FormatYUV420PackedSemiPlanar &&
34875a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        fmt != HAL_PIXEL_FORMAT_YV12) {
348803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        ALOGW("do not know color format 0x%x = %d", fmt, fmt);
3489229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return false;
349003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    }
349103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
3492b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    // TEMPORARY FIX for some vendors that advertise sliceHeight as 0
3493b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    if (params.nStride != 0 && params.nSliceHeight == 0) {
3494b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        ALOGW("using sliceHeight=%u instead of what codec advertised (=0)",
3495b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar                params.nFrameHeight);
3496b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        params.nSliceHeight = params.nFrameHeight;
3497b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    }
3498b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar
3499b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    // we need stride and slice-height to be non-zero
3500b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    if (params.nStride == 0 || params.nSliceHeight == 0) {
3501b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        ALOGW("cannot describe color format 0x%x = %d with stride=%u and sliceHeight=%u",
3502b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar                fmt, fmt, params.nStride, params.nSliceHeight);
3503b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        return false;
3504b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    }
3505b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar
350603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    // set-up YUV format
350703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mType = MediaImage::MEDIA_IMAGE_TYPE_YUV;
350803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mNumPlanes = 3;
350903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mBitDepth = 8;
351003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mOffset = 0;
351103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mColInc = 1;
351203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mRowInc = params.nStride;
351303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mHorizSubsampling = 1;
351403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mVertSubsampling = 1;
351503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
35165a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar    switch ((int)fmt) {
35175a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        case HAL_PIXEL_FORMAT_YV12:
35185a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            if (params.bUsingNativeBuffers) {
35195a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                size_t ystride = align(params.nStride, 16);
35205a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                size_t cstride = align(params.nStride / 2, 16);
35215a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.Y].mRowInc = ystride;
35225a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
35235a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mOffset = ystride * params.nSliceHeight;
35245a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mColInc = 1;
35255a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mRowInc = cstride;
35265a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mHorizSubsampling = 2;
35275a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mVertSubsampling = 2;
35285a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
35295a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mOffset = image.mPlane[image.V].mOffset
35305a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                        + (cstride * params.nSliceHeight / 2);
35315a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mColInc = 1;
35325a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mRowInc = cstride;
35335a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mHorizSubsampling = 2;
35345a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mVertSubsampling = 2;
35355a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                break;
35365a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            } else {
35375a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                // fall through as YV12 is used for YUV420Planar by some codecs
35385a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            }
35395a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
35405a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        case OMX_COLOR_FormatYUV420Planar:
354103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420PackedPlanar:
354203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight;
354303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mColInc = 1;
354403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mRowInc = params.nStride / 2;
354503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mHorizSubsampling = 2;
354603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mVertSubsampling = 2;
354703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
354803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset
354903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    + (params.nStride * params.nSliceHeight / 4);
355003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mColInc = 1;
355103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mRowInc = params.nStride / 2;
355203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mHorizSubsampling = 2;
355303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mVertSubsampling = 2;
355403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            break;
355503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
355603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420SemiPlanar:
355703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            // FIXME: NV21 for sw-encoder, NV12 for decoder and hw-encoder
355803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420PackedSemiPlanar:
355903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            // NV12
356003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight;
356103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mColInc = 2;
356203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mRowInc = params.nStride;
356303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mHorizSubsampling = 2;
356403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mVertSubsampling = 2;
356503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
356603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset + 1;
356703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mColInc = 2;
356803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mRowInc = params.nStride;
356903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mHorizSubsampling = 2;
357003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mVertSubsampling = 2;
357103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            break;
357203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
357303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        default:
357403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            TRESPASS();
357503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    }
3576229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    return true;
3577229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar}
3578229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3579229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar// static
3580229d242665c612fd97431d1e7ac004823b47f181Lajos Molnarbool ACodec::describeColorFormat(
3581229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        const sp<IOMX> &omx, IOMX::node_id node,
3582229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        DescribeColorFormatParams &describeParams)
3583229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar{
3584229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    OMX_INDEXTYPE describeColorFormatIndex;
3585229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    if (omx->getExtensionIndex(
3586229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            node, "OMX.google.android.index.describeColorFormat",
3587229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            &describeColorFormatIndex) != OK ||
3588229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        omx->getParameter(
3589229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            node, describeColorFormatIndex,
3590229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            &describeParams, sizeof(describeParams)) != OK) {
3591229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return describeDefaultColorFormat(describeParams);
3592229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    }
3593229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    return describeParams.sMediaImage.mType !=
3594229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
3595229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar}
3596229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3597229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar// static
3598229d242665c612fd97431d1e7ac004823b47f181Lajos Molnarbool ACodec::isFlexibleColorFormat(
3599229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar         const sp<IOMX> &omx, IOMX::node_id node,
36000d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar         uint32_t colorFormat, bool usingNativeBuffers, OMX_U32 *flexibleEquivalent) {
3601229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    DescribeColorFormatParams describeParams;
3602229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    InitOMXParams(&describeParams);
3603229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.eColorFormat = (OMX_COLOR_FORMATTYPE)colorFormat;
3604229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    // reasonable dummy values
3605229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nFrameWidth = 128;
3606229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nFrameHeight = 128;
3607229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nStride = 128;
3608229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nSliceHeight = 128;
36090d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    describeParams.bUsingNativeBuffers = (OMX_BOOL)usingNativeBuffers;
3610229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3611229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    CHECK(flexibleEquivalent != NULL);
3612229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3613229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    if (!describeColorFormat(omx, node, describeParams)) {
3614229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return false;
3615229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    }
3616229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3617229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    const MediaImage &img = describeParams.sMediaImage;
3618229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    if (img.mType == MediaImage::MEDIA_IMAGE_TYPE_YUV) {
3619229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        if (img.mNumPlanes != 3 ||
3620229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            img.mPlane[img.Y].mHorizSubsampling != 1 ||
3621229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            img.mPlane[img.Y].mVertSubsampling != 1) {
3622229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            return false;
3623229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
3624229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3625229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        // YUV 420
3626229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        if (img.mPlane[img.U].mHorizSubsampling == 2
3627229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.U].mVertSubsampling == 2
3628229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.V].mHorizSubsampling == 2
3629229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.V].mVertSubsampling == 2) {
3630229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            // possible flexible YUV420 format
3631229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            if (img.mBitDepth <= 8) {
3632229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar               *flexibleEquivalent = OMX_COLOR_FormatYUV420Flexible;
3633229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar               return true;
3634229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            }
3635229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
3636229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    }
3637229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    return false;
363803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar}
363903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
3640e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarstatus_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> &notify) {
3641e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    // TODO: catch errors an return them instead of using CHECK
364231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
364331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    InitOMXParams(&def);
3644e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    def.nPortIndex = portIndex;
364531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
364631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ(mOMX->getParameter(
364731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)),
364831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber             (status_t)OK);
364931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3650e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ((int)def.eDir,
3651e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            (int)(portIndex == kPortIndexOutput ? OMX_DirOutput : OMX_DirInput));
365231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
365331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    switch (def.eDomain) {
365431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainVideo:
365531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
365631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
3657e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            switch ((int)videoDef->eCompressionFormat) {
3658e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_VIDEO_CodingUnused:
3659e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3660e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(mIsEncoder ^ (portIndex == kPortIndexOutput));
3661e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
3662e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3663e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("stride", videoDef->nStride);
3664e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("slice-height", videoDef->nSliceHeight);
3665e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("color-format", videoDef->eColorFormat);
3666e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
36670d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                    if (mNativeWindow == NULL) {
36680d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        DescribeColorFormatParams describeParams;
36690d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        InitOMXParams(&describeParams);
36700d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.eColorFormat = videoDef->eColorFormat;
36710d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nFrameWidth = videoDef->nFrameWidth;
36720d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nFrameHeight = videoDef->nFrameHeight;
36730d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nStride = videoDef->nStride;
36740d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nSliceHeight = videoDef->nSliceHeight;
36750d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.bUsingNativeBuffers = OMX_FALSE;
36760d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar
36770d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        if (describeColorFormat(mOMX, mNode, describeParams)) {
36780d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                            notify->setBuffer(
36790d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                    "image-data",
36800d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                    ABuffer::CreateAsCopy(
36810d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                            &describeParams.sMediaImage,
36820d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                            sizeof(describeParams.sMediaImage)));
36835a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
36845a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                            MediaImage *img = &describeParams.sMediaImage;
36855a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                            ALOGV("[%s] MediaImage { F(%zux%zu) @%zu+%zu+%zu @%zu+%zu+%zu @%zu+%zu+%zu }",
36865a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                                    mComponentName.c_str(), img->mWidth, img->mHeight,
36875a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                                    img->mPlane[0].mOffset, img->mPlane[0].mColInc, img->mPlane[0].mRowInc,
36885a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                                    img->mPlane[1].mOffset, img->mPlane[1].mColInc, img->mPlane[1].mRowInc,
36895a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                                    img->mPlane[2].mOffset, img->mPlane[2].mColInc, img->mPlane[2].mRowInc);
36900d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        }
369103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    }
369203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
369391a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                    if (portIndex != kPortIndexOutput) {
369491a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                        // TODO: also get input crop
369591a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                        break;
369691a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                    }
369791a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar
3698e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_CONFIG_RECTTYPE rect;
3699e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&rect);
370091a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                    rect.nPortIndex = portIndex;
3701e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3702e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    if (mOMX->getConfig(
370391a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                mNode,
370491a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                (portIndex == kPortIndexOutput ?
370591a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                        OMX_IndexConfigCommonOutputCrop :
370691a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                        OMX_IndexConfigCommonInputCrop),
3707e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &rect, sizeof(rect)) != OK) {
3708e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nLeft = 0;
3709e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nTop = 0;
3710e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nWidth = videoDef->nFrameWidth;
3711e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nHeight = videoDef->nFrameHeight;
3712e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    }
371331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3714e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nLeft, 0);
3715e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nTop, 0);
3716e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nWidth, 0u);
3717e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nHeight, 0u);
3718e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_LE(rect.nLeft + rect.nWidth - 1, videoDef->nFrameWidth);
3719e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_LE(rect.nTop + rect.nHeight - 1, videoDef->nFrameHeight);
3720e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3721e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setRect(
3722577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            "crop",
3723577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nLeft,
3724577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nTop,
3725e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                            rect.nLeft + rect.nWidth - 1,
3726e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                            rect.nTop + rect.nHeight - 1);
3727e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3728e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3729e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
37304730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
37314730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP8:
37324730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP9:
37334730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                {
37344730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
37354730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    InitOMXParams(&vp8type);
37364730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    vp8type.nPortIndex = kPortIndexOutput;
37374730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    status_t err = mOMX->getParameter(
37384730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            mNode,
37394730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
37404730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            &vp8type,
37414730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            sizeof(vp8type));
37424730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
37434730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    if (err == OK) {
37444730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        AString tsSchema = "none";
37454730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        if (vp8type.eTemporalPattern
37464730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                == OMX_VIDEO_VPXTemporalLayerPatternWebRTC) {
37474730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            switch (vp8type.nTemporalLayerCount) {
37484730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 1:
37494730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
37504730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.1-layer";
37514730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
37524730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
37534730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 2:
37544730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
37554730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.2-layer";
37564730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
37574730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
37584730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 3:
37594730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
37604730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.3-layer";
37614730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
37624730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
37634730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                default:
37644730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
37654730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
37664730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
37674730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            }
37684730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        }
37694730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        notify->setString("ts-schema", tsSchema);
37704730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    }
37714730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    // Fall through to set up mime.
37724730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                }
37734730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
3774e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                default:
3775e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3776e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(mIsEncoder ^ (portIndex == kPortIndexInput));
3777e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    AString mime;
3778e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    if (GetMimeTypeForVideoCoding(
3779e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        videoDef->eCompressionFormat, &mime) != OK) {
3780e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", "application/octet-stream");
3781e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    } else {
3782e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", mime.c_str());
3783e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    }
3784e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3785e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
378631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            }
3787e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("width", videoDef->nFrameWidth);
3788e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("height", videoDef->nFrameHeight);
37895a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            ALOGV("[%s] %s format is %s", mComponentName.c_str(),
37905a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                    portIndex == kPortIndexInput ? "input" : "output",
37915a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                    notify->debugString().c_str());
37925a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
379331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
379431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
379531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
379631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainAudio:
379731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
379831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
379931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
380097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            switch ((int)audioDef->eEncoding) {
3801e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingPCM:
3802e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3803e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_PCMMODETYPE params;
3804e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3805e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3806e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3807e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3808e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioPcm,
3809e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3810e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3811e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
381214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_GT(params.nChannels, 0);
3813e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK(params.nChannels == 1 || params.bInterleaved);
3814e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(params.nBitPerSample, 16u);
381514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
381614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.eNumData,
381714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_NumericalDataSigned);
381814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
381914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.ePCMMode,
382014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_AUDIO_PCMModeLinear);
3821e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3822e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
3823e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
3824e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSamplingRate);
3825e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3826e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mChannelMaskPresent) {
3827e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("channel-mask", mChannelMask);
38288b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                    }
3829e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
38308b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                }
38319806555d3930be43e11106281dee354820ac1c88Andreas Huber
3832e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAAC:
3833e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3834e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AACPROFILETYPE params;
3835e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3836e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3837e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3838e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3839e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAac,
3840e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3841e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3842e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3843e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
3844e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
3845e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
3846e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
3847e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
3848e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3849e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAMR:
3850e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3851e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AMRTYPE params;
3852e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3853e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
38549806555d3930be43e11106281dee354820ac1c88Andreas Huber
3855e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3856e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAmr,
3857e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3858e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3859e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3860e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", 1);
3861e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) {
3862e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
3863e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_WB);
3864e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3865e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 16000);
3866e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    } else {
3867e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
3868e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
3869e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3870e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 8000);
3871e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
3872e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
3873e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
3874e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3875e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingFLAC:
3876e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3877e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_FLACTYPE params;
3878e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3879e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3880e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3881e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3882e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioFlac,
3883e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3884e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3885e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3886e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC);
3887e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
3888e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
3889e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
3890e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
3891e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3892e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingMP3:
3893e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3894e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_MP3TYPE params;
3895e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
3896e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3897e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3898e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_EQ(mOMX->getParameter(
3899e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                mNode, OMX_IndexParamAudioMp3,
3900e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &params, sizeof(params)),
3901e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                             (status_t)OK);
3902e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3903e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MPEG);
3904e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
3905e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
3906e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3907e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
3908e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3909e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingVORBIS:
3910e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3911e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_VORBISTYPE params;
3912e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
3913e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3914e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3915e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_EQ(mOMX->getParameter(
3916e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                mNode, OMX_IndexParamAudioVorbis,
3917e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &params, sizeof(params)),
3918e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                             (status_t)OK);
3919e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3920e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_VORBIS);
3921e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
3922e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
3923e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3924e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
3925e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
392697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                case OMX_AUDIO_CodingAndroidAC3:
392797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                {
392897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    OMX_AUDIO_PARAM_ANDROID_AC3TYPE params;
392997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    InitOMXParams(&params);
3930e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
393197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
393297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    CHECK_EQ((status_t)OK, mOMX->getParameter(
393397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            mNode,
393497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
393597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            &params,
393697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            sizeof(params)));
393797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
393897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AC3);
393997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("channel-count", params.nChannels);
394097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("sample-rate", params.nSampleRate);
394197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    break;
394297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                }
3943e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
39448a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                case OMX_AUDIO_CodingAndroidEAC3:
39458a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                {
39468a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    OMX_AUDIO_PARAM_ANDROID_EAC3TYPE params;
39478a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    InitOMXParams(&params);
39488a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    params.nPortIndex = portIndex;
39498a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
39508a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    CHECK_EQ((status_t)OK, mOMX->getParameter(
39518a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                            mNode,
39528a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
39538a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                            &params,
39548a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                            sizeof(params)));
39558a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
39568a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_EAC3);
39578a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setInt32("channel-count", params.nChannels);
39588a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setInt32("sample-rate", params.nSampleRate);
39598a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    break;
39608a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                }
39618a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
39628c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                case OMX_AUDIO_CodingAndroidOPUS:
39638c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                {
39648c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    OMX_AUDIO_PARAM_ANDROID_OPUSTYPE params;
39658c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    InitOMXParams(&params);
39668c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    params.nPortIndex = portIndex;
39678c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
39688c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    CHECK_EQ((status_t)OK, mOMX->getParameter(
39698c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            mNode,
39708c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus,
39718c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            &params,
39728c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            sizeof(params)));
39738c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
39748c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_OPUS);
39758c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("channel-count", params.nChannels);
39768c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("sample-rate", params.nSampleRate);
39778c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    break;
39788c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                }
39798c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
398010d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                case OMX_AUDIO_CodingG711:
398110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                {
398210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    OMX_AUDIO_PARAM_PCMMODETYPE params;
398310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    InitOMXParams(&params);
398410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    params.nPortIndex = portIndex;
398510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
398610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    CHECK_EQ((status_t)OK, mOMX->getParameter(
398710d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                            mNode,
398810d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                            (OMX_INDEXTYPE)OMX_IndexParamAudioPcm,
398910d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                            &params,
399010d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                            sizeof(params)));
399110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
399210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    const char *mime = NULL;
399310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    if (params.ePCMMode == OMX_AUDIO_PCMModeMULaw) {
399410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_G711_MLAW;
399510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    } else if (params.ePCMMode == OMX_AUDIO_PCMModeALaw) {
399610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_G711_ALAW;
399710d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    } else { // params.ePCMMode == OMX_AUDIO_PCMModeLinear
399810d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_RAW;
399910d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    }
400010d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setString("mime", mime);
400110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setInt32("channel-count", params.nChannels);
400210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setInt32("sample-rate", params.nSamplingRate);
400310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    break;
400410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                }
400541d3f579d2c166984958263533284209b90c87d5Marco Nelissen
400641d3f579d2c166984958263533284209b90c87d5Marco Nelissen                case OMX_AUDIO_CodingGSMFR:
400741d3f579d2c166984958263533284209b90c87d5Marco Nelissen                {
400841d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    OMX_AUDIO_PARAM_MP3TYPE params;
400941d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    InitOMXParams(&params);
401041d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    params.nPortIndex = portIndex;
401141d3f579d2c166984958263533284209b90c87d5Marco Nelissen
401241d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    CHECK_EQ(mOMX->getParameter(
401341d3f579d2c166984958263533284209b90c87d5Marco Nelissen                                mNode, OMX_IndexParamAudioPcm,
401441d3f579d2c166984958263533284209b90c87d5Marco Nelissen                                &params, sizeof(params)),
401541d3f579d2c166984958263533284209b90c87d5Marco Nelissen                             (status_t)OK);
401641d3f579d2c166984958263533284209b90c87d5Marco Nelissen
401741d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MSGSM);
401841d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    notify->setInt32("channel-count", params.nChannels);
401941d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    notify->setInt32("sample-rate", params.nSampleRate);
402041d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    break;
402110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                }
402210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
4023e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                default:
4024e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    ALOGE("UNKNOWN AUDIO CODING: %d\n", audioDef->eEncoding);
4025e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    TRESPASS();
4026e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
402731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
402831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
402931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
403031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        default:
403131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            TRESPASS();
403231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    }
403331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4034e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    return OK;
4035e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar}
4036e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4037e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarvoid ACodec::sendFormatChange(const sp<AMessage> &reply) {
40384e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    sp<AMessage> notify = mBaseOutputFormat->dup();
4039e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    notify->setInt32("what", kWhatOutputFormatChanged);
4040e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4041e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ(getPortFormat(kPortIndexOutput, notify), (status_t)OK);
4042e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4043e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    AString mime;
4044e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK(notify->findString("mime", &mime));
4045e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4046e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    int32_t left, top, right, bottom;
4047e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if (mime == MEDIA_MIMETYPE_VIDEO_RAW &&
4048e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        mNativeWindow != NULL &&
4049e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->findRect("crop", &left, &top, &right, &bottom)) {
4050e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        // notify renderer of the crop change
4051e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        // NOTE: native window uses extended right-bottom coordinate
4052e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        reply->setRect("crop", left, top, right + 1, bottom + 1);
4053e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    } else if (mime == MEDIA_MIMETYPE_AUDIO_RAW &&
4054e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar               (mEncoderDelay || mEncoderPadding)) {
4055e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        int32_t channelCount;
4056e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        CHECK(notify->findInt32("channel-count", &channelCount));
4057e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        size_t frameSize = channelCount * sizeof(int16_t);
4058e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        if (mSkipCutBuffer != NULL) {
4059e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            size_t prevbufsize = mSkipCutBuffer->size();
4060e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            if (prevbufsize != 0) {
4061ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                ALOGW("Replacing SkipCutBuffer holding %zu bytes", prevbufsize);
4062e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            }
4063e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        }
4064e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        mSkipCutBuffer = new SkipCutBuffer(
4065e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                mEncoderDelay * frameSize,
4066e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                mEncoderPadding * frameSize);
4067e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
4068e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
406931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->post();
407031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
407131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mSentFormat = true;
407231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber}
407331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
40745778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
4075cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    sp<AMessage> notify = mNotify->dup();
4076d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatError);
4077251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    ALOGE("signalError(omxError %#x, internalError %d)", error, internalError);
4078251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
4079251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (internalError == UNKNOWN_ERROR) { // find better error code
4080251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        const status_t omxStatus = statusFromOMXError(error);
4081251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        if (omxStatus != 0) {
4082251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            internalError = omxStatus;
4083251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        } else {
4084251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            ALOGW("Invalid OMX error %#x", error);
4085251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        }
4086251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
40875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("err", internalError);
4088251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    notify->setInt32("actionCode", ACTION_CODE_FATAL); // could translate from OMX error.
4089cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->post();
4090cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber}
4091cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber
4092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4094eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberACodec::PortDescription::PortDescription() {
4095eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
4096eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4097496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t ACodec::requestIDRFrame() {
4098496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    if (!mIsEncoder) {
4099496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        return ERROR_UNSUPPORTED;
4100496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    }
4101496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4102496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    OMX_CONFIG_INTRAREFRESHVOPTYPE params;
4103496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    InitOMXParams(&params);
4104496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4105496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.nPortIndex = kPortIndexOutput;
4106496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.IntraRefreshVOP = OMX_TRUE;
4107496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4108496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    return mOMX->setConfig(
4109496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            mNode,
4110496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            OMX_IndexConfigVideoIntraVOPRefresh,
4111496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            &params,
4112496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            sizeof(params));
4113496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
4114496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4115eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubervoid ACodec::PortDescription::addBuffer(
4116eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        IOMX::buffer_id id, const sp<ABuffer> &buffer) {
4117eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBufferIDs.push_back(id);
4118eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBuffers.push_back(buffer);
4119eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
4120eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4121eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersize_t ACodec::PortDescription::countBuffers() {
4122eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.size();
4123eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
4124eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4125eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberIOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const {
4126eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.itemAt(index);
4127eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
4128eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4129eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const {
4130eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBuffers.itemAt(index);
4131eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
4132eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4133eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber////////////////////////////////////////////////////////////////////////////////
4134eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4135f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
4136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : AState(parentState),
4137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mCodec(codec) {
4138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4140ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas HuberACodec::BaseState::PortMode ACodec::BaseState::getPortMode(
4141ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
4142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return KEEP_BUFFERS;
4143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4145f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
4146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatInputBufferFilled:
4148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onInputBufferFilled(msg);
4150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatOutputBufferDrained:
4154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onOutputBufferDrained(msg);
4156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatOMXMessage:
4160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXMessage(msg);
4162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
41641dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        case ACodec::kWhatSetSurface:
41651dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        {
41661dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            sp<AReplyToken> replyID;
41671dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            CHECK(msg->senderAwaitsResponse(&replyID));
41681dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
41691dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            sp<RefBase> obj;
41701dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            CHECK(msg->findObject("surface", &obj));
41711dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
41721dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            status_t err = mCodec->handleSetSurface(static_cast<Surface *>(obj.get()));
41731dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
41741dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            sp<AMessage> response = new AMessage;
41751dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            response->setInt32("err", err);
41761dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            response->postReply(replyID);
41771dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            break;
41781dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
41791dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
41807cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
4181d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        case ACodec::kWhatUsePersistentInputSurface:
41827cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
41837cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
4184251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            // This may result in an app illegal state exception.
41857cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            ALOGE("Message 0x%x was not handled", msg->what());
41867cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
41877cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            return true;
41887cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
41897cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4190ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        case ACodec::kWhatOMXDied:
4191ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        {
4192251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            // This will result in kFlagSawMediaServerDie handling in MediaCodec.
4193ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            ALOGE("OMX/mediaserver died, signalling error!");
4194ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT);
4195ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            break;
4196ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        }
4197ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
419830358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        case ACodec::kWhatReleaseCodecInstance:
419930358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        {
420030358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            ALOGI("[%s] forcing the release of codec",
420130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar                    mCodec->mComponentName.c_str());
420230358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            status_t err = mCodec->mOMX->freeNode(mCodec->mNode);
420330358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            ALOGE_IF("[%s] failed to release codec instance: err=%d",
420430358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar                       mCodec->mComponentName.c_str(), err);
420530358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            sp<AMessage> notify = mCodec->mNotify->dup();
420630358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
420730358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            notify->post();
420830358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            break;
420930358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        }
421030358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar
4211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
4213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4218f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
4219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t type;
4220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findInt32("type", &type));
4221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
42225e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // there is a possibility that this is an outstanding message for a
42235e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // codec that we have already destroyed
4224ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    if (mCodec->mNode == 0) {
42255e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar        ALOGI("ignoring message as already freed component: %s",
42265e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar                msg->debugString().c_str());
42275e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar        return true;
42285e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    }
42295e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar
4230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::node_id nodeID;
4231609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("node", (int32_t*)&nodeID));
4232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(nodeID, mCodec->mNode);
4233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (type) {
4235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EVENT:
4236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t event, data1, data2;
4238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("event", &event));
4239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data1", &data1));
4240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data2", &data2));
4241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
42420af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            if (event == OMX_EventCmdComplete
42430af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data1 == OMX_CommandFlush
42440af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data2 == (int32_t)OMX_ALL) {
42450af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // Use of this notification is not consistent across
42460af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // implementations. We'll drop this notification and rely
42470af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // on flush-complete notifications on the individual port
42480af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // indices instead.
42490af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
42500af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                return true;
42510af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            }
42520af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
4253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEvent(
4254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_EVENTTYPE>(event),
4255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data1),
4256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data2));
4257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EMPTY_BUFFER_DONE:
4260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
4262609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
4263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEmptyBufferDone(bufferID);
4265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::FILL_BUFFER_DONE:
4268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
4270609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
4271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t rangeOffset, rangeLength, flags;
4273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs;
4274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_offset", &rangeOffset));
4276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_length", &rangeLength));
4277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("flags", &flags));
4278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt64("timestamp", &timeUs));
4279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXFillBufferDone(
4281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    bufferID,
4282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (size_t)rangeOffset, (size_t)rangeLength,
4283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (OMX_U32)flags,
4284784e24e386b088c05d653ab482f2e95cb53e3d01Andy Hung                    timeUs);
4285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
4289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4293f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEvent(
4294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (event != OMX_EventError) {
4296ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        ALOGV("[%s] EVENT(%d, 0x%08x, 0x%08x)",
4297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mCodec->mComponentName.c_str(), event, data1, data2);
4298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return false;
4300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4302ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGE("[%s] ERROR(0x%08x)", mCodec->mComponentName.c_str(), data1);
4303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4304251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // verify OMX component sends back an error we expect.
4305251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    OMX_ERRORTYPE omxError = (OMX_ERRORTYPE)data1;
4306251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (!isOMXError(omxError)) {
4307251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        ALOGW("Invalid OMX error %#x", omxError);
4308251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        omxError = OMX_ErrorUndefined;
4309251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
4310251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    mCodec->signalError(omxError);
4311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4315f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID) {
4316ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGV("[%s] onOMXEmptyBufferDone %u",
4317349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber         mCodec->mComponentName.c_str(), bufferID);
4318349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
4320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexInput, bufferID);
4321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
4323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
4324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
432596e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // We're in "store-metadata-in-buffers" mode, the underlying
432696e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // OMX component had access to data that's implicitly refcounted
432796e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // by this "MediaBuffer" object. Now that the OMX component has
432896e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // told us that it's done with the input buffer, we can decrement
432996e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // the mediaBuffer's reference count.
433096e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    info->mData->setMediaBufferBase(NULL);
4331d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
4333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            postFillThisBuffer(info);
4340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
4345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();  // Not currently used
4346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4353f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
4354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
4355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
4356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
4359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
4361d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatFillThisBuffer);
4362609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    notify->setInt32("buffer-id", info->mBufferID);
4363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mData->meta()->clear();
43652d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    notify->setBuffer("buffer", info->mData);
4366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
43671d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec);
4368609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    reply->setInt32("buffer-id", info->mBufferID);
4369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setMessage("reply", reply);
4371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->post();
4373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
4375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4377f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
4378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
4379609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
43802d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    sp<ABuffer> buffer;
4381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t err = OK;
43825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool eos = false;
4383a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar    PortMode mode = getPortMode(kPortIndexInput);
43845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
43852d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    if (!msg->findBuffer("buffer", &buffer)) {
4386a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar        /* these are unfilled buffers returned by client */
4387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findInt32("err", &err));
4388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
43897fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        if (err == OK) {
43907fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            /* buffers with no errors are returned on MediaCodec.flush */
43917fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            mode = KEEP_BUFFERS;
43927fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        } else {
43937fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            ALOGV("[%s] saw error %d instead of an input buffer",
43947fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                 mCodec->mComponentName.c_str(), err);
43957fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            eos = true;
43967fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        }
43973831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
43982d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber        buffer.clear();
4399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
44015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
44025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
44035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
44045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = ERROR_END_OF_STREAM;
44055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
44065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
4408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_UPSTREAM);
4409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
4411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
44155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (eos) {
4416dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (!mCodec->mPortEOS[kPortIndexInput]) {
4417dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
4418dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mInputEOSResult = err;
4419dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
4420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
44265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
4427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int64_t timeUs;
4428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
4429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
4431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t isCSD;
4433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
4434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
4435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
4436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
44375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (eos) {
44385778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    flags |= OMX_BUFFERFLAG_EOS;
44395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
44405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer != info->mData) {
4442ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] Needs to copy input data for buffer %u. (%p != %p)",
4443d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(),
4444d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         bufferID,
4445d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         buffer.get(), info->mData.get());
4446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    CHECK_LE(buffer->size(), info->mData->capacity());
4448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    memcpy(info->mData->data(), buffer->data(), buffer->size());
4449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
4450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4451078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
4452ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] calling emptyBuffer %u w/ codec specific data",
4453078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID);
44545778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else if (flags & OMX_BUFFERFLAG_EOS) {
4455ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] calling emptyBuffer %u w/ EOS",
44565778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str(), bufferID);
4457078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                } else {
4458d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
4459ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGI("[%s] calling emptyBuffer %u w/ time %lld us",
4460ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                         mCodec->mComponentName.c_str(), bufferID, (long long)timeUs);
4461d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#else
4462ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] calling emptyBuffer %u w/ time %lld us",
4463ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                         mCodec->mComponentName.c_str(), bufferID, (long long)timeUs);
4464d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
4465078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                }
4466349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4467d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
4468d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ACodec::BufferStats stats;
4469d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
4470d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mFillBufferDoneTimeUs = -1ll;
4471d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mCodec->mBufferStats.add(timeUs, stats);
4472d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
4473d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4474054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                if (mCodec->mStoreMetaDataInOutputBuffers) {
4475054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    // try to submit an output buffer for each input buffer
4476054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    PortMode outputMode = getPortMode(kPortIndexOutput);
4477054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4478054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    ALOGV("MetaDataBuffersToSubmit=%u portMode=%s",
4479054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            mCodec->mMetaDataBuffersToSubmit,
4480054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            (outputMode == FREE_BUFFERS ? "FREE" :
4481054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                             outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
4482054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    if (outputMode == RESUBMIT_BUFFERS) {
4483e53350373ac516257b4f8956ff1e3f1ac48f607eLajos Molnar                        mCodec->submitOutputMetaDataBuffer();
4484054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    }
4485054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                }
4486054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
4488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
4489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
4490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
4491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            buffer->size(),
4492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            flags,
4493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            timeUs),
4494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
44985778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (!eos) {
44995778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    getMoreInputDataIfPossible();
45005778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
45015778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] Signalled EOS on the input port",
45025778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str());
45035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
45045778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
45055778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mInputEOSResult = err;
45065778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
4507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
4508dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (err != ERROR_END_OF_STREAM) {
45093856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port "
4510dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         "due to error %d",
4511dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str(), err);
4512dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                } else {
45133856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port",
4514dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str());
4515dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
4516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4517ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                ALOGV("[%s] calling emptyBuffer %u signalling EOS",
4518349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                     mCodec->mComponentName.c_str(), bufferID);
4519349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
4521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
4522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
4523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
4524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
4525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_BUFFERFLAG_EOS,
4526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0),
4527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexInput] = true;
4532dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                mCodec->mInputEOSResult = err;
4533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4536625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih
4537625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih        default:
4538625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
4539625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih            break;
4540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4543f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::getMoreInputDataIfPossible() {
4544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
4545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
4546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *eligible = NULL;
4549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
4551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
4552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
4554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
4555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // There's already a "read" pending.
4556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
4557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
4559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_US) {
4561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            eligible = info;
4562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (eligible == NULL) {
4566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
4567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(eligible);
4570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4572f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXFillBufferDone(
4573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferID,
4574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        size_t rangeOffset, size_t rangeLength,
4575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 flags,
4576784e24e386b088c05d653ab482f2e95cb53e3d01Andy Hung        int64_t timeUs) {
4577609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] onOMXFillBufferDone %u time %" PRId64 " us, flags = 0x%08x",
45785778822d86b0337407514b9372562b86edfa91cdAndreas Huber         mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
4579349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
4581d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4582d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
4583d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    index = mCodec->mBufferStats.indexOfKey(timeUs);
4584d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (index >= 0) {
4585d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
4586d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
4587d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4588d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ALOGI("frame PTS %lld: %lld",
4589d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                timeUs,
4590d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
4591d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4592d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mCodec->mBufferStats.removeItemsAt(index);
4593d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats = NULL;
4594d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
4595d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
4596d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
4598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
4599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
4601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4602054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mDequeuedAt = ++mCodec->mDequeueCounter;
4603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
4604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
4606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4613a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            if (rangeLength == 0 && (!(flags & OMX_BUFFERFLAG_EOS)
4614a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                    || mCodec->mPortEOS[kPortIndexOutput])) {
4615609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                ALOGV("[%s] calling fillBuffer %u",
46165778822d86b0337407514b9372562b86edfa91cdAndreas Huber                     mCodec->mComponentName.c_str(), info->mBufferID);
4617349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
46185778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK_EQ(mCodec->mOMX->fillBuffer(
46195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mCodec->mNode, info->mBufferID),
46205778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         (status_t)OK);
4621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
46225778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
46235778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
46245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
462531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4626577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            sp<AMessage> reply =
46271d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar                new AMessage(kWhatOutputBufferDrained, mCodec);
4628577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
46294bdda35319d5f46efea2089b865c8a64816389cdMarco Nelissen            if (!mCodec->mSentFormat && rangeLength > 0) {
4630577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->sendFormatChange(reply);
46315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
4632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4633308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            if (mCodec->mUseMetadataOnEncoderOutput) {
4634308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                native_handle_t* handle =
4635308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        *(native_handle_t**)(info->mData->data() + 4);
4636308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setPointer("handle", handle);
4637308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeOffset", rangeOffset);
4638308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeLength", rangeLength);
4639308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            } else {
4640308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->setRange(rangeOffset, rangeLength);
4641308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            }
4642496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#if 0
464321ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen            if (mCodec->mNativeWindow == NULL) {
4644496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                if (IsIDR(info->mData)) {
4645496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                    ALOGI("IDR frame");
4646496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                }
46475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
464821ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen#endif
4649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
46508b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            if (mCodec->mSkipCutBuffer != NULL) {
46518b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                mCodec->mSkipCutBuffer->submit(info->mData);
46528b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            }
46535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mData->meta()->setInt64("timeUs", timeUs);
4654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
46555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4656d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatDrainThisBuffer);
4657609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            notify->setInt32("buffer-id", info->mBufferID);
46582d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            notify->setBuffer("buffer", info->mData);
46595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("flags", flags);
4660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4661609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            reply->setInt32("buffer-id", info->mBufferID);
4662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
46635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setMessage("reply", reply);
4664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
46655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->post();
46665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
46675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
4668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (flags & OMX_BUFFERFLAG_EOS) {
46705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
46715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                sp<AMessage> notify = mCodec->mNotify->dup();
4673d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar                notify->setInt32("what", CodecBase::kWhatEOS);
4674dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                notify->setInt32("err", mCodec->mInputEOSResult);
4675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->post();
4676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexOutput] = true;
4678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
4685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
4687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
4688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4695f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
4696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
4697609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
4698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
4699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
4700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
4701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM);
4702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4703577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    android_native_rect_t crop;
4704577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    if (msg->findRect("crop",
4705577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            &crop.left, &crop.top, &crop.right, &crop.bottom)) {
4706577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar        CHECK_EQ(0, native_window_set_crop(
4707577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->mNativeWindow.get(), &crop));
4708577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    }
4709577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
4710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t render;
4711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mNativeWindow != NULL
47126aade6058521b0dbd35a9a4620f4d04f02f90444Marco Nelissen            && msg->findInt32("render", &render) && render != 0
471379ee2399b67c7a11042c5904dc1309712a76f8cbJianzheng Zhou            && info->mData != NULL && info->mData->size() != 0) {
47146fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        ATRACE_NAME("render");
4715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The client wants this buffer to be rendered.
4716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4717fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        int64_t timestampNs = 0;
4718fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        if (!msg->findInt64("timestampNs", &timestampNs)) {
4719fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // TODO: it seems like we should use the timestamp
4720fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // in the (media)buffer as it potentially came from
4721fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // an input surface, but we did not propagate it prior to
4722fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // API 20.  Perhaps check for target SDK version.
4723fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#if 0
4724fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            if (info->mData->meta()->findInt64("timeUs", &timestampNs)) {
472547aea1f7c58f5302b16822f9e7e1763f2af04ef5Lajos Molnar                ALOGV("using buffer PTS of %" PRId64, timestampNs);
4726fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar                timestampNs *= 1000;
4727fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            }
4728fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#endif
4729fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
4730fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
47315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err;
4732fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        err = native_window_set_buffers_timestamp(mCodec->mNativeWindow.get(), timestampNs);
4733fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        if (err != OK) {
4734fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            ALOGW("failed to set buffer timestamp: %d", err);
4735fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
4736fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
47375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if ((err = mCodec->mNativeWindow->queueBuffer(
4738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNativeWindow.get(),
47391e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                    info->mGraphicBuffer.get(), -1)) == OK) {
4740cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
4741cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        } else {
4742251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
4743cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
4744cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        }
4745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
47466fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        if (mCodec->mNativeWindow != NULL &&
47476fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar            (info->mData == NULL || info->mData->size() != 0)) {
47486fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar            ATRACE_NAME("frame-drop");
47496fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        }
4750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_US;
4751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
4754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
4759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // We cannot resubmit the buffer we just rendered, dequeue
4762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // the spare instead.
4763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info = mCodec->dequeueBufferFromNativeWindow();
4765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (!mCodec->mPortEOS[kPortIndexOutput]) {
4772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // We cannot resubmit the buffer we just rendered, dequeue
4774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // the spare instead.
4775f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info = mCodec->dequeueBufferFromNativeWindow();
4777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
4778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4779c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                if (info != NULL) {
4780609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                    ALOGV("[%s] calling fillBuffer %u",
4781c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                         mCodec->mComponentName.c_str(), info->mBufferID);
4782349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4783c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
4784c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                             (status_t)OK);
4785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4786c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4787c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                }
4788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
4795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
4797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
4798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4805f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::UninitializedState::UninitializedState(ACodec *codec)
4806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4809c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::UninitializedState::stateEntered() {
4810c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("Now uninitialized");
4811ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4812ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (mDeathNotifier != NULL) {
4813f888020c6e2735624f2b2a30e72aca24e17b8b4dMarco Nelissen        IInterface::asBinder(mCodec->mOMX)->unlinkToDeath(mDeathNotifier);
4814ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
4815ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
4816ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4817ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNativeWindow.clear();
4818ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    mCodec->mNode = 0;
4819ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mOMX.clear();
4820ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mQuirks = 0;
4821ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mFlags = 0;
4822308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    mCodec->mUseMetadataOnEncoderOutput = 0;
4823ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mComponentName.clear();
4824c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4825c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4826f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
4827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatSetup:
4831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onSetup(msg);
4833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
48385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case ACodec::kWhatAllocateComponent:
48395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
48405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            onAllocateComponent(msg);
48415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            handled = true;
48425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
48435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
48445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatShutdown:
4846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4847c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
4848c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
4849c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
485054b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            ALOGW_IF(keepComponentAllocated,
485154b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar                     "cannot keep component allocated on shutdown in Uninitialized state");
4852c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4854d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
4855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
4856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4858c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
4859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatFlush:
4862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4864d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
4865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
4866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4868c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
4869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
487130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        case ACodec::kWhatReleaseCodecInstance:
487230358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        {
487330358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            // nothing to do, as we have already signaled shutdown
487430358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            handled = true;
487530358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            break;
487630358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        }
487730358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar
4878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
4880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4885f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::UninitializedState::onSetup(
4886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4887c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (onAllocateComponent(msg)
4888c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            && mCodec->mLoadedState->onConfigureComponent(msg)) {
4889c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mLoadedState->onStart();
4890c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
48915778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
48925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4893c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
48945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onAllocateComponent");
48955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4896ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    CHECK(mCodec->mNode == 0);
48975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMXClient client;
489948a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung    if (client.connect() != OK) {
490048a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung        mCodec->signalError(OMX_ErrorUndefined, NO_INIT);
490148a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung        return false;
490248a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung    }
4903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<IOMX> omx = client.interface();
4905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
49061d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec);
4907ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4908ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mDeathNotifier = new DeathNotifier(notify);
4909f888020c6e2735624f2b2a30e72aca24e17b8b4dMarco Nelissen    if (IInterface::asBinder(omx)->linkToDeath(mDeathNotifier) != OK) {
4910ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // This was a local binder, if it dies so do we, we won't care
4911ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // about any notifications in the afterlife.
4912ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
4913ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
4914ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4915e671207115fac3914134c61b336d5fa0242c68caAndreas Huber    Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs;
49165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    AString mime;
4918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
49195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString componentName;
4920d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint32_t quirks = 0;
49217791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen    int32_t encoder = false;
49225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findString("componentName", &componentName)) {
4923e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        ssize_t index = matchingCodecs.add();
4924e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        OMXCodec::CodecNameAndQuirks *entry = &matchingCodecs.editItemAt(index);
4925e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        entry->mName = String8(componentName.c_str());
4926afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
4927e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        if (!OMXCodec::findCodecQuirks(
4928e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                    componentName.c_str(), &entry->mQuirks)) {
4929e671207115fac3914134c61b336d5fa0242c68caAndreas Huber            entry->mQuirks = 0;
4930afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
49315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
49325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(msg->findString("mime", &mime));
49335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
49345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("encoder", &encoder)) {
49355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder = false;
49365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
49375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
49385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMXCodec::findMatchingCodecs(
49395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mime.c_str(),
49405778822d86b0337407514b9372562b86edfa91cdAndreas Huber                encoder, // createEncoder
49415778822d86b0337407514b9372562b86edfa91cdAndreas Huber                NULL,  // matchComponentName
49425778822d86b0337407514b9372562b86edfa91cdAndreas Huber                0,     // flags
4943e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                &matchingCodecs);
49445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
49451065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
49461065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    sp<CodecObserver> observer = new CodecObserver;
4947ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    IOMX::node_id node = 0;
49481065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
49499f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu    status_t err = OMX_ErrorComponentNotFound;
49501065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
49511065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            ++matchIndex) {
4952e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        componentName = matchingCodecs.itemAt(matchIndex).mName.string();
4953e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        quirks = matchingCodecs.itemAt(matchIndex).mQuirks;
4954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4955da153975581fb3161a30452348a5b26ee72d9255Elliott Hughes        pid_t tid = gettid();
4956078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        int prevPriority = androidGetThreadPriority(tid);
4957078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
49589f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu        err = omx->allocateNode(componentName.c_str(), observer, &node);
4959078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, prevPriority);
4960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
49611065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        if (err == OK) {
49621065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            break;
49637a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He        } else {
49647a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He            ALOGW("Allocating component '%s' failed, try next one.", componentName.c_str());
49651065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
49661065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
4967ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        node = 0;
49681065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    }
49691065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
4970ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    if (node == 0) {
49715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!mime.empty()) {
49729f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu            ALOGE("Unable to instantiate a %scoder for type '%s' with err %#x.",
49739f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu                    encoder ? "en" : "de", mime.c_str(), err);
49745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
49759f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu            ALOGE("Unable to instantiate codec '%s' with err %#x.", componentName.c_str(), err);
49765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
4977c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
497852e88b2986536e83a7a6da63461556b8734a85f3Ronghua Wu        mCodec->signalError((OMX_ERRORTYPE)err, makeNoSideEffectStatus(err));
4979c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
4980c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
4981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
49821d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    notify = new AMessage(kWhatOMXMessage, mCodec);
4983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    observer->setNotificationMessage(notify);
4984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mComponentName = componentName;
4986ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    mCodec->mFlags = 0;
4987ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
4988ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (componentName.endsWith(".secure")) {
4989ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        mCodec->mFlags |= kFlagIsSecure;
49901713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        mCodec->mFlags |= kFlagIsGrallocUsageProtected;
49910167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
4992ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
4993ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
4994afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mCodec->mQuirks = quirks;
4995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mOMX = omx;
4996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mNode = node;
4997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
49985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
49995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
5000d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatComponentAllocated);
50015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setString("componentName", mCodec->mComponentName.c_str());
50025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
50035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5004c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5005c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mCodec->changeState(mCodec->mLoadedState);
5006c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5007c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
50085778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
50095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5010c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
5011c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5012c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas HuberACodec::LoadedState::LoadedState(ACodec *codec)
5013c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    : BaseState(codec) {
5014c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
5015c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5016c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::stateEntered() {
5017c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
5018c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5019f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mPortEOS[kPortIndexInput] =
5020f6f38287b97ec69b169387add6458f859b770e65Andreas Huber        mCodec->mPortEOS[kPortIndexOutput] = false;
5021f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
5022f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mInputEOSResult = OK;
5023f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
5024054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mDequeueCounter = 0;
5025054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mMetaDataBuffersToSubmit = 0;
5026a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    mCodec->mRepeatFrameDelayUs = -1ll;
5027e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mInputFormat.clear();
5028e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mOutputFormat.clear();
50294e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    mCodec->mBaseOutputFormat.clear();
5030054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5031c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (mCodec->mShutdownInProgress) {
5032c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
5033c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5034c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mShutdownInProgress = false;
5035c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mKeepComponentAllocated = false;
5036c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5037c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        onShutdown(keepComponentAllocated);
5038c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
503954b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    mCodec->mExplicitShutdown = false;
5040f393c33e65ae51a7cf168b4e15771b152f996b32Wei Jia
5041f393c33e65ae51a7cf168b4e15771b152f996b32Wei Jia    mCodec->processDeferredMessages();
5042c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
5043c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5044c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
5045c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (!keepComponentAllocated) {
5046c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK);
5047c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5048c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->changeState(mCodec->mUninitializedState);
5049c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
5050c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
505154b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    if (mCodec->mExplicitShutdown) {
505254b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        sp<AMessage> notify = mCodec->mNotify->dup();
5053d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
505454b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        notify->post();
505554b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        mCodec->mExplicitShutdown = false;
505654b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    }
5057c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
5058c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5059c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
5060c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool handled = false;
5061c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5062c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    switch (msg->what()) {
5063c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatConfigureComponent:
5064c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
5065c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onConfigureComponent(msg);
5066c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
5067c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
5068c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
5069c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
50707cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
50717cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
50727cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            onCreateInputSurface(msg);
50737cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
50747cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
50757cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
50767cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
5077d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        case ACodec::kWhatUsePersistentInputSurface:
5078d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        {
5079d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            onUsePersistentInputSurface(msg);
5080d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            handled = true;
5081d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            break;
5082d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        }
5083d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5084c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatStart:
5085c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
5086c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onStart();
5087c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
5088c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
5089c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
5090c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5091c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatShutdown:
5092c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
5093c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
5094c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
5095c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
5096c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
509754b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
5098c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onShutdown(keepComponentAllocated);
5099c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5100c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
5101c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
5102c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
5103c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5104c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatFlush:
5105c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
5106c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
5107d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
5108c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->post();
5109c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5110c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
5111c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
5112c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
5113c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5114c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        default:
5115c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            return BaseState::onMessageReceived(msg);
5116c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
5117c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5118c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return handled;
5119c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
5120c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5121c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onConfigureComponent(
51225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg) {
51235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onConfigureComponent");
51245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5125ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    CHECK(mCodec->mNode != 0);
51265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
51275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString mime;
51285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findString("mime", &mime));
51295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
51305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mCodec->configureCodec(mime.c_str(), msg);
51315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
51325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
5133c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        ALOGE("[%s] configureCodec returning error %d",
5134c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber              mCodec->mComponentName.c_str(), err);
5135c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber
5136251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5137c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
51385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
51405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
51415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
5142d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatComponentConfigured);
5143e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("input-format", mCodec->mInputFormat);
5144e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("output-format", mCodec->mOutputFormat);
51455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
51465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5147c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5148c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
51495778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
51505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5151d291c222357303b9611cab89d0c3b047584ef377Chong Zhangstatus_t ACodec::LoadedState::setupInputSurface() {
5152d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    status_t err = OK;
5153a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
5154d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mRepeatFrameDelayUs > 0ll) {
5155a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        err = mCodec->mOMX->setInternalOption(
5156a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                mCodec->mNode,
5157a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                kPortIndexInput,
5158a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY,
5159a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                &mCodec->mRepeatFrameDelayUs,
5160a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                sizeof(mCodec->mRepeatFrameDelayUs));
5161a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
5162a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (err != OK) {
5163a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            ALOGE("[%s] Unable to configure option to repeat previous "
5164a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  "frames (err %d)",
5165a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  mCodec->mComponentName.c_str(),
5166a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  err);
5167d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
5168a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
5169a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
5170a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
5171d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mMaxPtsGapUs > 0ll) {
517294ee4b708acfa941581160b267afb79192b1d816Chong Zhang        err = mCodec->mOMX->setInternalOption(
517394ee4b708acfa941581160b267afb79192b1d816Chong Zhang                mCodec->mNode,
517494ee4b708acfa941581160b267afb79192b1d816Chong Zhang                kPortIndexInput,
517594ee4b708acfa941581160b267afb79192b1d816Chong Zhang                IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP,
517694ee4b708acfa941581160b267afb79192b1d816Chong Zhang                &mCodec->mMaxPtsGapUs,
517794ee4b708acfa941581160b267afb79192b1d816Chong Zhang                sizeof(mCodec->mMaxPtsGapUs));
517894ee4b708acfa941581160b267afb79192b1d816Chong Zhang
517994ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (err != OK) {
518094ee4b708acfa941581160b267afb79192b1d816Chong Zhang            ALOGE("[%s] Unable to configure max timestamp gap (err %d)",
518172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    mCodec->mComponentName.c_str(),
518272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    err);
5183d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
51842c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
51852c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
51862c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
5187d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mMaxFps > 0) {
518837b2b389139ed638831e49708c947863eef631efRonghua Wu        err = mCodec->mOMX->setInternalOption(
518937b2b389139ed638831e49708c947863eef631efRonghua Wu                mCodec->mNode,
519037b2b389139ed638831e49708c947863eef631efRonghua Wu                kPortIndexInput,
519137b2b389139ed638831e49708c947863eef631efRonghua Wu                IOMX::INTERNAL_OPTION_MAX_FPS,
519237b2b389139ed638831e49708c947863eef631efRonghua Wu                &mCodec->mMaxFps,
519337b2b389139ed638831e49708c947863eef631efRonghua Wu                sizeof(mCodec->mMaxFps));
519437b2b389139ed638831e49708c947863eef631efRonghua Wu
519537b2b389139ed638831e49708c947863eef631efRonghua Wu        if (err != OK) {
519637b2b389139ed638831e49708c947863eef631efRonghua Wu            ALOGE("[%s] Unable to configure max fps (err %d)",
519737b2b389139ed638831e49708c947863eef631efRonghua Wu                    mCodec->mComponentName.c_str(),
519837b2b389139ed638831e49708c947863eef631efRonghua Wu                    err);
5199d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
520037b2b389139ed638831e49708c947863eef631efRonghua Wu        }
520137b2b389139ed638831e49708c947863eef631efRonghua Wu    }
520237b2b389139ed638831e49708c947863eef631efRonghua Wu
5203d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mTimePerCaptureUs > 0ll
52042c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            && mCodec->mTimePerFrameUs > 0ll) {
52052c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        int64_t timeLapse[2];
52062c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[0] = mCodec->mTimePerFrameUs;
52072c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[1] = mCodec->mTimePerCaptureUs;
52082c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        err = mCodec->mOMX->setInternalOption(
52092c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                mCodec->mNode,
52102c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                kPortIndexInput,
52112c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                IOMX::INTERNAL_OPTION_TIME_LAPSE,
52122c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                &timeLapse[0],
52132c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                sizeof(timeLapse));
52142c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
52152c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (err != OK) {
52162c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            ALOGE("[%s] Unable to configure time lapse (err %d)",
52172c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    mCodec->mComponentName.c_str(),
52182c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    err);
5219d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
52202c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
52212c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
522272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
5223d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mCreateInputBuffersSuspended) {
522472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        bool suspend = true;
522572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        err = mCodec->mOMX->setInternalOption(
522672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                mCodec->mNode,
522772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                kPortIndexInput,
522872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                IOMX::INTERNAL_OPTION_SUSPEND,
522972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                &suspend,
523072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                sizeof(suspend));
523172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
523272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
523372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("[%s] Unable to configure option to suspend (err %d)",
523494ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  mCodec->mComponentName.c_str(),
523594ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  err);
5236d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
523794ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
523894ee4b708acfa941581160b267afb79192b1d816Chong Zhang    }
523994ee4b708acfa941581160b267afb79192b1d816Chong Zhang
5240d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    return OK;
5241d291c222357303b9611cab89d0c3b047584ef377Chong Zhang}
5242d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5243d291c222357303b9611cab89d0c3b047584ef377Chong Zhangvoid ACodec::LoadedState::onCreateInputSurface(
5244d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        const sp<AMessage> & /* msg */) {
5245d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    ALOGV("onCreateInputSurface");
5246d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5247d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<AMessage> notify = mCodec->mNotify->dup();
5248d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    notify->setInt32("what", CodecBase::kWhatInputSurfaceCreated);
5249d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5250d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<IGraphicBufferProducer> bufferProducer;
5251d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    status_t err = mCodec->mOMX->createInputSurface(
5252d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            mCodec->mNode, kPortIndexInput, &bufferProducer);
5253d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5254d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (err == OK) {
5255d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        err = setupInputSurface();
5256d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    }
5257d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
52587cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err == OK) {
52597cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setObject("input-surface",
52607cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                new BufferProducerWrapper(bufferProducer));
52617cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else {
52627cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // Can't use mCodec->signalError() here -- MediaCodec won't forward
52637cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // the error through because it's in the "configured" state.  We
52647cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // send a kWhatInputSurfaceCreated with an error value instead.
52657cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGE("[%s] onCreateInputSurface returning error %d",
52667cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                mCodec->mComponentName.c_str(), err);
52677cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setInt32("err", err);
52687cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
52697cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->post();
52707cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
52717cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
5272d291c222357303b9611cab89d0c3b047584ef377Chong Zhangvoid ACodec::LoadedState::onUsePersistentInputSurface(
5273d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        const sp<AMessage> &msg) {
5274d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    ALOGV("onUsePersistentInputSurface");
5275d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5276d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<AMessage> notify = mCodec->mNotify->dup();
5277d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    notify->setInt32("what", CodecBase::kWhatInputSurfaceAccepted);
5278d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5279d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<RefBase> obj;
5280d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    CHECK(msg->findObject("input-surface", &obj));
5281d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<PersistentSurface> surface = static_cast<PersistentSurface *>(obj.get());
5282d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5283d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    status_t err = mCodec->mOMX->usePersistentInputSurface(
5284d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            mCodec->mNode, kPortIndexInput, surface->getBufferConsumer());
5285d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5286d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (err == OK) {
5287d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        err = setupInputSurface();
5288d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    }
5289d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5290d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (err != OK) {
5291d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        // Can't use mCodec->signalError() here -- MediaCodec won't forward
5292d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        // the error through because it's in the "configured" state.  We
5293d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        // send a kWhatInputSurfaceAccepted with an error value instead.
5294d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        ALOGE("[%s] onUsePersistentInputSurface returning error %d",
5295d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                mCodec->mComponentName.c_str(), err);
5296d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        notify->setInt32("err", err);
5297d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    }
5298d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    notify->post();
5299d291c222357303b9611cab89d0c3b047584ef377Chong Zhang}
5300d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5301c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onStart() {
53025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onStart");
53035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
53045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ(mCodec->mOMX->sendCommand(
53055778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
5306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
5307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->changeState(mCodec->mLoadedToIdleState);
5309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5313f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
5314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5317f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::LoadedToIdleState::stateEntered() {
53183856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
5319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5320cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    status_t err;
5321cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    if ((err = allocateBuffers()) != OK) {
532229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to allocate buffers after transitioning to IDLE state "
5323cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             "(error 0x%08x)",
5324cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             err);
5325cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
5326251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
532791bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber
532891bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber        mCodec->changeState(mCodec->mLoadedState);
5329cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    }
5330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5332f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::LoadedToIdleState::allocateBuffers() {
5333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
5334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
5336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
5337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mCodec->allocateBuffersOnPort(kPortIndexOutput);
5340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5342f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
5343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
534472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
5345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
5348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
53516507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
53526507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
53536507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
53546507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
53556507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
53566507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
53576463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatResume:
53586463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
53596463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We'll be active soon enough.
53606463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
53616463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
53626463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
53636463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatFlush:
53646463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
53656463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We haven't even started yet, so we're flushed alright...
53666463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            sp<AMessage> notify = mCodec->mNotify->dup();
5367d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
53686463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->post();
53696463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
53706463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
53716463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
5372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
5374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5377f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onOMXEvent(
5378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
5383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
5384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
5386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting),
5387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
5388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mIdleToExecutingState);
5390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5401f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
5402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5405f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToExecutingState::stateEntered() {
54063856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
5407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5409f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
5410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
541172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
5412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
5415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5418d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatResume:
5419d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
5420d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We'll be active soon enough.
5421d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
5422d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
5423d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
5424d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatFlush:
5425d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
5426d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We haven't even started yet, so we're flushed alright...
5427d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
5428d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
5429d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->post();
5430d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
5431d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
5432d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
5433d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
54346507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
54356507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
54366507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
54376507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
54386507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
54396507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
5440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
5442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5445f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onOMXEvent(
5446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
5451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateExecuting);
5452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mExecutingState->resume();
5454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingState);
5455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5466f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingState::ExecutingState(ACodec *codec)
5467349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    : BaseState(codec),
5468349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber      mActive(false) {
5469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5471f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
5472ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
5473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
5474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5476054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputMetaBuffers() {
5477054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // submit as many buffers as there are input buffers with the codec
5478054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // in case we are in port reconfiguring
5479054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
5480054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
5481054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5482054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) {
5483054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            if (mCodec->submitOutputMetaDataBuffer() != OK)
5484054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                break;
5485054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
5486054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
54874dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
54884dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
54894dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
5490054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
5491054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5492054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitRegularOutputBuffers() {
5493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
5494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
5495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mCodec->mNativeWindow != NULL) {
5497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(info->mStatus == BufferInfo::OWNED_BY_US
5498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
5499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
5501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                continue;
5502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
5504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
5505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5507ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        ALOGV("[%s] calling fillBuffer %u",
5508349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str(), info->mBufferID);
5509349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
5511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
5512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
5514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5517054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputBuffers() {
5518c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar    submitRegularOutputBuffers();
5519054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mCodec->mStoreMetaDataInOutputBuffers) {
5520054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        submitOutputMetaBuffers();
5521054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
5522054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
5523054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5524f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::resume() {
5525349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    if (mActive) {
55263856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] We're already active, no need to resume.",
5527349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str());
5528349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5529349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        return;
5530349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    }
5531349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    submitOutputBuffers();
5533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
55343cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    // Post all available input buffers
5535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_GT(mCodec->mBuffers[kPortIndexInput].size(), 0u);
55363cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); i++) {
55373cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
55383cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_US) {
55393cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar            postFillThisBuffer(info);
55403cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        }
55413cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    }
5542349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5543349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    mActive = true;
5544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5546f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::stateEntered() {
55473856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
5548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->processDeferredMessages();
5550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5552f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
5553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5558c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
5559c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
5560c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
5561c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5562c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mShutdownInProgress = true;
556354b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
5564c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mKeepComponentAllocated = keepComponentAllocated;
5565c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5566349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
5567349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
5569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
5570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
5571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingToIdleState);
5573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
55807a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong            ALOGV("[%s] ExecutingState flushing now "
5581ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                 "(codec owns %zu/%zu input, %zu/%zu output).",
5582d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mComponentName.c_str(),
5583d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
5584d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexInput].size(),
5585d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
5586d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexOutput].size());
5587d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
5588349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
5589349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
5591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandFlush, OMX_ALL),
5592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
5593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mFlushingState);
5595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatResume:
5600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            resume();
5602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5607496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
5608496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
5609496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            status_t err = mCodec->requestIDRFrame();
5610496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            if (err != OK) {
5611496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                ALOGW("Requesting an IDR frame failed.");
5612496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            }
5613496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5614496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            handled = true;
5615496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
5616496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
5617496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5618a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
5619a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
5620a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
5621a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
5622a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5623a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = mCodec->setParameters(params);
5624a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5625a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> reply;
5626a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            if (msg->findMessage("reply", &reply)) {
5627a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->setInt32("err", err);
5628a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->post();
5629a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            }
5630a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5631a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            handled = true;
5632a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
5633a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
5634a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
56357cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
56367cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
56376507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
56387cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
56397cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
56407cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
56417cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
56424dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
56434dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        case kWhatSubmitOutputMetaDataBufferIfEOS:
56444dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        {
56454dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            if (mCodec->mPortEOS[kPortIndexInput] &&
56464dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    !mCodec->mPortEOS[kPortIndexOutput]) {
56474dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                status_t err = mCodec->submitOutputMetaDataBuffer();
56484dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                if (err == OK) {
56494dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
56504dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                }
56514dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            }
56524dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            return true;
56534dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        }
56544dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
5655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5663a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t ACodec::setParameters(const sp<AMessage> &params) {
5664a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    int32_t videoBitrate;
5665530fdbdc1b5491f3fbf172752834d1515701e142Lajos Molnar    if (params->findInt32("video-bitrate", &videoBitrate)) {
5666a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        OMX_VIDEO_CONFIG_BITRATETYPE configParams;
5667a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        InitOMXParams(&configParams);
5668a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nPortIndex = kPortIndexOutput;
5669a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nEncodeBitrate = videoBitrate;
5670a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5671a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        status_t err = mOMX->setConfig(
5672a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                mNode,
5673a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                OMX_IndexConfigVideoBitrate,
5674a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                &configParams,
5675a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                sizeof(configParams));
5676a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5677a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        if (err != OK) {
5678a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
5679a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                   videoBitrate, err);
5680a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5681a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            return err;
5682a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
5683a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    }
5684a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
568572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    int64_t skipFramesBeforeUs;
568672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (params->findInt64("skip-frames-before", &skipFramesBeforeUs)) {
568772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        status_t err =
568872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mOMX->setInternalOption(
568972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     mNode,
569072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     kPortIndexInput,
569172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     IOMX::INTERNAL_OPTION_START_TIME,
569272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     &skipFramesBeforeUs,
569372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     sizeof(skipFramesBeforeUs));
569472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
569572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
569672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("Failed to set parameter 'skip-frames-before' (err %d)", err);
569772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            return err;
569872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
569972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
570072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
5701e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    int32_t dropInputFrames;
5702e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    if (params->findInt32("drop-input-frames", &dropInputFrames)) {
5703e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        bool suspend = dropInputFrames != 0;
5704e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
5705b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err =
5706b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            mOMX->setInternalOption(
5707e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     mNode,
5708e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     kPortIndexInput,
5709e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     IOMX::INTERNAL_OPTION_SUSPEND,
5710e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     &suspend,
5711b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber                     sizeof(suspend));
5712b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
5713b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
5714b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err);
5715b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
5716b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
5717b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    }
5718b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
5719b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    int32_t dummy;
5720b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    if (params->findInt32("request-sync", &dummy)) {
5721b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err = requestIDRFrame();
5722b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
5723b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
5724b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Requesting a sync frame failed w/ err %d", err);
5725b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
5726b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
5727e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    }
5728e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
57298db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    float rate;
57308db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    if (params->findFloat("operating-rate", &rate) && rate > 0) {
57318db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        status_t err = setOperatingRate(rate, mIsVideo);
57328db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        if (err != OK) {
57338db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu            ALOGE("Failed to set parameter 'operating-rate' (err %d)", err);
57348db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu            return err;
57358db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        }
57368db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    }
57378db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu
5738a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return OK;
5739a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
5740a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
57416507d14c6d10f93d390de62b9eed267f9b544985Andy McFaddenvoid ACodec::onSignalEndOfInputStream() {
57426507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    sp<AMessage> notify = mNotify->dup();
5743d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatSignaledInputEOS);
57446507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
57456507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    status_t err = mOMX->signalEndOfInputStream(mNode);
57466507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    if (err != OK) {
57476507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        notify->setInt32("err", err);
57486507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    }
57496507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->post();
57506507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden}
57516507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
5752f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onOMXEvent(
5753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventPortSettingsChanged:
5756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
5758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
575931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
5760054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mCodec->mMetaDataBuffersToSubmit = 0;
5761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
5762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
5763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_CommandPortDisable, kPortIndexOutput),
5764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
5765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5766349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                mCodec->freeOutputBuffersNotOwnedByComponent();
5767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
576931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            } else if (data2 == OMX_IndexConfigCommonOutputCrop) {
577031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
5771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
5772ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08x",
5773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->mComponentName.c_str(), data2);
5774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5775f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventBufferFlag:
5780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5791f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
5792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ACodec *codec)
5793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5796f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
5797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
5798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput) {
5799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return FREE_BUFFERS;
5800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
5803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
5805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5807f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onMessageReceived(
5808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
5809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5814349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case kWhatResume:
5815e6eea3a6b6e0cf92287ec1ceb8350f201d17e1acPer Persson        case kWhatSetParameters:
5816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5817349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            if (msg->what() == kWhatResume) {
58183856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
5819349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            }
5820349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
5822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5834f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::OutputPortSettingsChangedState::stateEntered() {
58353856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now handling output port settings change",
5836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mCodec->mComponentName.c_str());
5837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5839f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onOMXEvent(
5840f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
5845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
5846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
58473856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now disabled.",
5848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
5849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5850f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mCodec->mBuffers[kPortIndexOutput].isEmpty());
5851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mDealer[kPortIndexOutput].clear();
5852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
5854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput),
5855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
5856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5857cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                status_t err;
5858cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                if ((err = mCodec->allocateBuffersOnPort(
5859cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                                kPortIndexOutput)) != OK) {
586029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("Failed to allocate output port buffers after "
5861cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         "port reconfiguration (error 0x%08x)",
5862cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         err);
5863cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
5864251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5865d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
5866755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // This is technically not correct, but appears to be
5867755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the only way to free the component instance.
5868755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // Controlled transitioning from excecuting->idle
5869755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // and idle->loaded seem impossible probably because
5870755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the output port never finishes re-enabling.
5871755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mShutdownInProgress = true;
5872755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mKeepComponentAllocated = false;
5873755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->changeState(mCodec->mLoadedState);
5874cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                }
5875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
5877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
5878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
5879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
588031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
588131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
58823856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now reenabled.",
5883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
5884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5885349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                if (mCodec->mExecutingState->active()) {
5886349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    mCodec->mExecutingState->submitOutputBuffers();
5887349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                }
5888349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mExecutingState);
5890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
5892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
5895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
5899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5904f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
59055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : BaseState(codec),
59065778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mComponentNowIdle(false) {
5907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5909f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
5910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
5916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
5917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
5918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
5924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5937f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::stateEntered() {
59383856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
593931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
59405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mComponentNowIdle = false;
594131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mCodec->mSentFormat = false;
5942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5944f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onOMXEvent(
5945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
5950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
5951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
59525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mComponentNowIdle = true;
59535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            changeStateIfWeOwnAllBuffers();
5955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5959349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
5960349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventBufferFlag:
5961349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
5962349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We're shutting down and don't care about this anymore.
5963349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
5964349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
5965349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
59700af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
5971f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
59725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
5973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->sendCommand(
5974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded),
5975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
5976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexInput), (status_t)OK);
5978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexOutput), (status_t)OK);
5979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
59800167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown)
59810167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && mCodec->mNativeWindow != NULL) {
5982bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // We push enough 1x1 blank buffers to ensure that one of
5983bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // them has made it to the display.  This allows the OMX
5984bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // component teardown to zero out any protected buffers
5985bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // without the risk of scanning out one of those buffers.
5986b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar            pushBlankBuffersToNativeWindow(mCodec->mNativeWindow.get());
5987bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
5988bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
5989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mIdleToLoadedState);
5990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5993f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onInputBufferFilled(
5994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
5995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
5996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
5998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6000f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onOutputBufferDrained(
6001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
6002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
6003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
6005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
6008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6009f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
6010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
6011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6013f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
6014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
6015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
6017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
6018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
6020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
6026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
6028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
6029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
6030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
6035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
6039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6041f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToLoadedState::stateEntered() {
60423856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
6043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6045f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onOMXEvent(
6046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
6048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
6049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
6051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateLoaded);
6052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6053c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->changeState(mCodec->mLoadedState);
6054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
6060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
6064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6065f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::FlushingState::FlushingState(ACodec *codec)
6066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
6067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6069f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::stateEntered() {
60703856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
6071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
6073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6075f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
6076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
6077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
6079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
6080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6081f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
6082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
6086f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing this right now.
6088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6089f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
6094f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6095f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
6098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6100f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onOMXEvent(
6101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6102ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGV("[%s] FlushingState onOMXEvent(%u,%d)",
6103ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar            mCodec->mComponentName.c_str(), event, (OMX_S32)data1);
6104d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
6105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
6106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
6107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandFlush);
6109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
6111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(!mFlushComplete[data2]);
6112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mFlushComplete[data2] = true;
6113e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber
6114e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                if (mFlushComplete[kPortIndexInput]
6115e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                        && mFlushComplete[kPortIndexOutput]) {
6116e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                    changeStateIfWeOwnAllBuffers();
6117e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                }
6118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
6119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, OMX_ALL);
6120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexInput]);
6121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexOutput]);
6122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                changeStateIfWeOwnAllBuffers();
6124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
6125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6129349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
6130349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
61311d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec);
6132349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("type", omx_message::EVENT);
6133609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            msg->setInt32("node", mCodec->mNode);
6134349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("event", event);
6135349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data1", data1);
6136349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data2", data2);
6137349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
61383856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
6139349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                 mCodec->mComponentName.c_str());
6140349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6141349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mCodec->deferMessage(msg);
6142349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6143349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
6144349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
6145349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
6148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
6151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6153f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
6154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
6155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
6157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6159f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
6160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
6161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
6163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6165f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
6166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mFlushComplete[kPortIndexInput]
6167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mFlushComplete[kPortIndexOutput]
6168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mCodec->allYourBuffersAreBelongToUs()) {
61697e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // We now own all buffers except possibly those still queued with
61707e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // the native window for rendering. Let's get those back as well.
61717e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
61727e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
6173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
6174d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatFlushCompleted);
6175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->post();
6176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->mPortEOS[kPortIndexInput] =
6178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mPortEOS[kPortIndexOutput] = false;
6179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6180dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber        mCodec->mInputEOSResult = OK;
6181dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
6182f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        if (mCodec->mSkipCutBuffer != NULL) {
6183f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen            mCodec->mSkipCutBuffer->clear();
6184f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        }
6185f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen
6186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mExecutingState);
6187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
6191