ACodec.cpp revision d36a023778256f0550e9a09e9993c066e8a3c7d7
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
6131dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // for meta data mode, we move dequeud buffers to the new surface.
6141dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // for non-meta mode, we must move all registered buffers
6151dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    for (size_t i = 0; i < buffers.size(); ++i) {
6161dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        const BufferInfo &info = buffers[i];
6171dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        // skip undequeued buffers for meta data mode
6181dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        if (mStoreMetaDataInOutputBuffers
6191dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                && info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
6201dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            ALOGV("skipping buffer %p", info.mGraphicBuffer->getNativeBuffer());
6211dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            continue;
6221dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
6231dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGV("attaching buffer %p", info.mGraphicBuffer->getNativeBuffer());
6241dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
6251dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        err = surface->attachBuffer(info.mGraphicBuffer->getNativeBuffer());
6261dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        if (err != OK) {
6271dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            ALOGE("failed to attach buffer %p to the new surface: %s (%d)",
6281dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    info.mGraphicBuffer->getNativeBuffer(),
6291dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    strerror(-err), -err);
6301dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            return err;
6311dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
6321dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6331dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
6341dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // cancel undequeued buffers to new surface
6351dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (!mStoreMetaDataInOutputBuffers) {
6361dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        for (size_t i = 0; i < buffers.size(); ++i) {
6371dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            const BufferInfo &info = buffers[i];
6381dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
6391dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                ALOGV("canceling buffer %p", info.mGraphicBuffer->getNativeBuffer());
6401dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                err = nativeWindow->cancelBuffer(
6411dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                        nativeWindow, info.mGraphicBuffer->getNativeBuffer(), -1);
6421dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                if (err != OK) {
6431dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    ALOGE("failed to cancel buffer %p to the new surface: %s (%d)",
6441dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                            info.mGraphicBuffer->getNativeBuffer(),
6451dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                            strerror(-err), -err);
6461dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    return err;
6471dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                }
6481dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            }
6491dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
6501dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        // disallow further allocation
6511dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        (void)surface->getIGraphicBufferProducer()->allowAllocation(false);
6521dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6531dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
654484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar    // push blank buffers to previous window if requested
655484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar    if (mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown) {
656484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar        pushBlankBuffersToNativeWindow(mNativeWindow.get());
657484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar    }
658484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar
6591dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    mNativeWindow = nativeWindow;
6601dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    return OK;
6611dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar}
6621dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
663f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mDealer[portIndex] == NULL);
667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mBuffers[portIndex].isEmpty());
668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
671054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (mStoreMetaDataInOutputBuffers) {
672054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputMetaDataBuffers();
673054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
674054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputBuffersFromNativeWindow();
675054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
6765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
6775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
6785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
6795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = portIndex;
680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
6825778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err == OK) {
685609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGV("[%s] Allocating %u buffers of size %u on %s port",
6865778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mComponentName.c_str(),
6875778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    def.nBufferCountActual, def.nBufferSize,
6885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    portIndex == kPortIndexInput ? "input" : "output");
689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            size_t totalSize = def.nBufferCountActual * def.nBufferSize;
6915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
6945778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
6955778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(mem.get() != NULL);
696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
697ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                BufferInfo info;
698ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                info.mStatus = BufferInfo::OWNED_BY_US;
699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
700afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                uint32_t requiresAllocateBufferBit =
701afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                    (portIndex == kPortIndexInput)
702afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        ? OMXCodec::kRequiresAllocateBufferOnInputPorts
703afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        : OMXCodec::kRequiresAllocateBufferOnOutputPorts;
7041065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
705308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                if ((portIndex == kPortIndexInput && (mFlags & kFlagIsSecure))
706308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        || mUseMetadataOnEncoderOutput) {
707ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    mem.clear();
708ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
709ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    void *ptr;
710ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->allocateBuffer(
711ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, def.nBufferSize, &info.mBufferID,
712ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            &ptr);
713ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
714308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    int32_t bufSize = mUseMetadataOnEncoderOutput ?
715308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                            (4 + sizeof(buffer_handle_t)) : def.nBufferSize;
716308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
717308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    info.mData = new ABuffer(ptr, bufSize);
718ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                } else if (mQuirks & requiresAllocateBufferBit) {
7195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    err = mOMX->allocateBufferWithBackup(
720ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, mem, &info.mBufferID);
7215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
722ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->useBuffer(mNode, portIndex, mem, &info.mBufferID);
723ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                }
724ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
725ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                if (mem != NULL) {
726ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    info.mData = new ABuffer(mem->pointer(), def.nBufferSize);
7275778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
7281065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
7295778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mBuffers[portIndex].push(info);
7301065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            }
7311065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
7325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
7355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
7365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> notify = mNotify->dup();
739d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatBuffersAllocated);
7405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("portIndex", portIndex);
742eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
743eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    sp<PortDescription> desc = new PortDescription;
744eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
7455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
746eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        const BufferInfo &info = mBuffers[portIndex][i];
7475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
748eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        desc->addBuffer(info.mBufferID, info.mData);
749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
751eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    notify->setObject("portDesc", desc);
7525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->post();
7535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7571dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t ACodec::setupNativeWindowSizeFormatAndUsage(ANativeWindow *nativeWindow /* nonnull */) {
7581dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    OMX_PARAM_PORTDEFINITIONTYPE def;
7591dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    InitOMXParams(&def);
7601dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    def.nPortIndex = kPortIndexOutput;
7611dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
7621dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    status_t err = mOMX->getParameter(
7631dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
7641dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
7651dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != OK) {
7661dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
7671dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7681dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
7691dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    OMX_U32 usage = 0;
7701dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
7711dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != 0) {
7721dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGW("querying usage flags from OMX IL component failed: %d", err);
7731dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        // XXX: Currently this error is logged, but not fatal.
7741dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        usage = 0;
7751dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7761dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    int omxUsage = usage;
7771dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
7781dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mFlags & kFlagIsGrallocUsageProtected) {
7791dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        usage |= GRALLOC_USAGE_PROTECTED;
7801dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7811dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
782b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar    usage |= GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP;
783b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar
7841dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    ALOGV("gralloc usage: %#x(OMX) => %#x(ACodec)", omxUsage, usage);
7851dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    return setNativeWindowSizeFormatAndUsage(
7861dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            nativeWindow,
7871dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            def.format.video.nFrameWidth,
7881dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            def.format.video.nFrameHeight,
7891dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            def.format.video.eColorFormat,
7901dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            mRotationDegrees,
7911dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            usage);
7921dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar}
7931dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
7941dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t ACodec::configureOutputBuffersFromNativeWindow(
7951dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        OMX_U32 *bufferCount, OMX_U32 *bufferSize,
7961dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        OMX_U32 *minUndequeuedBuffers) {
7971dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    OMX_PARAM_PORTDEFINITIONTYPE def;
7981dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    InitOMXParams(&def);
7991dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    def.nPortIndex = kPortIndexOutput;
8001dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
8011dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    status_t err = mOMX->getParameter(
8021dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
8031dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
8041dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err == OK) {
8051dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        err = setupNativeWindowSizeFormatAndUsage(mNativeWindow.get());
8061dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
8071dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != OK) {
8081dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
8091dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
8101dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
811ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // Exits here for tunneled video playback codecs -- i.e. skips native window
812ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // buffer allocation step as this is managed by the tunneled OMX omponent
813ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // itself and explicitly sets def.nBufferCountActual to 0.
814ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    if (mTunneled) {
815ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        ALOGV("Tunneled Playback: skipping native window buffer allocation.");
816ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        def.nBufferCountActual = 0;
817ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        err = mOMX->setParameter(
818ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
819ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
820ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *minUndequeuedBuffers = 0;
821ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *bufferCount = 0;
822ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *bufferSize = 0;
823ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        return err;
824ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    }
825ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
826054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *minUndequeuedBuffers = 0;
827258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    err = mNativeWindow->query(
828258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
829054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (int *)minUndequeuedBuffers);
830258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
831258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    if (err != 0) {
83229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
833258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                strerror(-err), -err);
834258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        return err;
835258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
836258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
837e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // FIXME: assume that surface is controlled by app (native window
838e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // returns the number for the case when surface is not controlled by app)
8391faa41704e0b976e546321effcb09a85767d51baLajos Molnar    // FIXME2: This means that minUndeqeueudBufs can be 1 larger than reported
8401faa41704e0b976e546321effcb09a85767d51baLajos Molnar    // For now, try to allocate 1 more buffer, but don't fail if unsuccessful
841e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar
842e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // Use conservative allocation while also trying to reduce starvation
843e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //
844e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // 1. allocate at least nBufferCountMin + minUndequeuedBuffers - that is the
845e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //    minimum needed for the consumer to be able to work
846e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // 2. try to allocate two (2) additional buffers to reduce starvation from
847e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //    the consumer
8481faa41704e0b976e546321effcb09a85767d51baLajos Molnar    //    plus an extra buffer to account for incorrect minUndequeuedBufs
8491faa41704e0b976e546321effcb09a85767d51baLajos Molnar    for (OMX_U32 extraBuffers = 2 + 1; /* condition inside loop */; extraBuffers--) {
850e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        OMX_U32 newBufferCount =
851e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            def.nBufferCountMin + *minUndequeuedBuffers + extraBuffers;
852258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        def.nBufferCountActual = newBufferCount;
853258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        err = mOMX->setParameter(
854258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
855258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
856e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        if (err == OK) {
857e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            *minUndequeuedBuffers += extraBuffers;
858e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            break;
859e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        }
860e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar
861609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGW("[%s] setting nBufferCountActual to %u failed: %d",
862e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar                mComponentName.c_str(), newBufferCount, err);
863e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        /* exit condition */
864e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        if (extraBuffers == 0) {
865258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            return err;
866258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        }
867258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
868258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffer_count(
870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(), def.nBufferCountActual);
871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
87329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                -err);
875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
878054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferCount = def.nBufferCountActual;
879054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferSize =  def.nBufferSize;
880054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
881054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
882054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
883054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputBuffersFromNativeWindow() {
884054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
885054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
886054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
887054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
888054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
889e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    mNumUndequeuedBuffers = minUndequeuedBuffers;
890054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
8913298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia    if (!mStoreMetaDataInOutputBuffers) {
8923298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia        static_cast<Surface*>(mNativeWindow.get())
8933298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia                ->getIGraphicBufferProducer()->allowAllocation(true);
8943298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia    }
8953298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia
896609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Allocating %u buffers from a native window of size %u on "
897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         "output port",
898054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount, bufferSize);
899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Dequeue buffers and send them to OMX
901054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
9028ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev        ANativeWindowBuffer *buf;
9031e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
90529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
91074006804065941841883c4b46ee785070164023fJamie Gennis        BufferInfo info;
91174006804065941841883c4b46ee785070164023fJamie Gennis        info.mStatus = BufferInfo::OWNED_BY_US;
912054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(NULL /* data */, bufferSize /* capacity */);
91374006804065941841883c4b46ee785070164023fJamie Gennis        info.mGraphicBuffer = graphicBuffer;
91474006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].push(info);
91574006804065941841883c4b46ee785070164023fJamie Gennis
916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferId;
917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &bufferId);
919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
920609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGE("registering GraphicBuffer %u with OMX IL component failed: "
92174006804065941841883c4b46ee785070164023fJamie Gennis                 "%d", i, err);
922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
92574006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
92674006804065941841883c4b46ee785070164023fJamie Gennis
927609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGV("[%s] Registered graphic buffer with ID %u (pointer = %p)",
928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mComponentName.c_str(),
929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             bufferId, graphicBuffer.get());
930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelStart;
933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelEnd;
934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // If an error occurred while dequeuing we need to cancel any buffers
937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // that were dequeued.
938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelStart = 0;
93974006804065941841883c4b46ee785070164023fJamie Gennis        cancelEnd = mBuffers[kPortIndexOutput].size();
940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
941054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // Return the required minimum undequeued buffers to the native window.
942054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelStart = bufferCount - minUndequeuedBuffers;
943054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelEnd = bufferCount;
944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
9483fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        status_t error = cancelBufferToNativeWindow(info);
9493fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        if (err == 0) {
9503fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia            err = error;
9513fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        }
952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9543298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia    if (!mStoreMetaDataInOutputBuffers) {
9553298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia        static_cast<Surface*>(mNativeWindow.get())
9563298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia                ->getIGraphicBufferProducer()->allowAllocation(false);
9573298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia    }
9583298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia
959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
962054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputMetaDataBuffers() {
963054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
964054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
965054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
966054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
967054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
968e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    mNumUndequeuedBuffers = minUndequeuedBuffers;
969054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
970609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Allocating %u meta buffers on output port",
971054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount);
972054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
973054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    size_t totalSize = bufferCount * 8;
974054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mDealer[kPortIndexOutput] = new MemoryDealer(totalSize, "ACodec");
975054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
976054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // Dequeue buffers and send them to OMX
977054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
978054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo info;
979054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
980054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mGraphicBuffer = NULL;
981054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mDequeuedAt = mDequeueCounter;
982054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
983054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        sp<IMemory> mem = mDealer[kPortIndexOutput]->allocate(
984054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                sizeof(struct VideoDecoderOutputMetaData));
985054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(mem.get() != NULL);
986054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(mem->pointer(), mem->size());
987054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
988054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // we use useBuffer for metadata regardless of quirks
989054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        err = mOMX->useBuffer(
990054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mNode, kPortIndexOutput, mem, &info.mBufferID);
991054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
992054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        mBuffers[kPortIndexOutput].push(info);
993054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
994609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGV("[%s] allocated meta buffer with ID %u (pointer = %p)",
995054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mComponentName.c_str(), info.mBufferID, mem->pointer());
996054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
997054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
998054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mMetaDataBuffersToSubmit = bufferCount - minUndequeuedBuffers;
999054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
1000054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
1001054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1002054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::submitOutputMetaDataBuffer() {
1003054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mStoreMetaDataInOutputBuffers);
1004054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mMetaDataBuffersToSubmit == 0)
1005054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return OK;
1006054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1007054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *info = dequeueBufferFromNativeWindow();
1008054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (info == NULL)
1009054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return ERROR_IO;
1010054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1011609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] submitting output meta buffer ID %u for graphic buffer %p",
1012054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          mComponentName.c_str(), info->mBufferID, info->mGraphicBuffer.get());
1013054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1014054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    --mMetaDataBuffersToSubmit;
1015054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK_EQ(mOMX->fillBuffer(mNode, info->mBufferID),
1016054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             (status_t)OK);
1017054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1018054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
1019054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return OK;
1020054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
1021054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1022f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
1023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
1024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1025609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Calling cancelBuffer on buffer %u",
1026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mComponentName.c_str(), info->mBufferID);
1027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int err = mNativeWindow->cancelBuffer(
10291e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        mNativeWindow.get(), info->mGraphicBuffer.get(), -1);
1030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10313fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia    ALOGW_IF(err != 0, "[%s] can not return buffer %u to native window",
10323fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia            mComponentName.c_str(), info->mBufferID);
1033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
1035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10363fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia    return err;
1037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1039f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
10408ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev    ANativeWindowBuffer *buf;
1041054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mNativeWindow.get() != NULL);
1042ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
1043ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    if (mTunneled) {
1044ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        ALOGW("dequeueBufferFromNativeWindow() should not be called in tunnel"
1045ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad              " video playback mode mode!");
1046ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        return NULL;
1047ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    }
1048ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
10491e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    if (native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf) != 0) {
105029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("dequeueBuffer failed.");
1051c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber        return NULL;
1052c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
1053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1054054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *oldest = NULL;
1055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
1056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
1057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
1058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1059054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mGraphicBuffer != NULL &&
1060054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            info->mGraphicBuffer->handle == buf->handle) {
1061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus,
1062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (int)BufferInfo::OWNED_BY_NATIVE_WINDOW);
1063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
1065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
1067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1068054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1069054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW &&
1070054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (oldest == NULL ||
1071054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             // avoid potential issues from counter rolling over
1072054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mDequeueCounter - info->mDequeuedAt >
1073054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    mDequeueCounter - oldest->mDequeuedAt)) {
1074054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            oldest = info;
1075054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
1076054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1077054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1078054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (oldest) {
1079054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(mStoreMetaDataInOutputBuffers);
1080054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1081054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // discard buffer in LRU info and replace with new buffer
1082054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mGraphicBuffer = new GraphicBuffer(buf, false);
1083054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mStatus = BufferInfo::OWNED_BY_US;
1084054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1085d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        mOMX->updateGraphicBufferInMeta(
1086d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                mNode, kPortIndexOutput, oldest->mGraphicBuffer,
1087d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                oldest->mBufferID);
1088054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1089d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        VideoDecoderOutputMetaData *metaData =
1090d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar            reinterpret_cast<VideoDecoderOutputMetaData *>(
1091d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                    oldest->mData->base());
1092d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        CHECK_EQ(metaData->eType, kMetadataBufferTypeGrallocSource);
1093d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar
1094d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
1095ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                (unsigned)(oldest - &mBuffers[kPortIndexOutput][0]),
1096054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mDequeueCounter - oldest->mDequeuedAt,
1097d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                metaData->pHandle,
1098d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                oldest->mGraphicBuffer->handle, oldest->mData->base());
1099054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1100054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return oldest;
1101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
1104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
1106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1108f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
1109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[portIndex].size(); i-- > 0;) {
1110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, freeBuffer(portIndex, i));
1111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDealer[portIndex].clear();
1114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1118349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huberstatus_t ACodec::freeOutputBuffersNotOwnedByComponent() {
1119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
1120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
1121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
1122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
11232ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // At this time some buffers may still be with the component
11242ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // or being drained.
11252ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT &&
11262ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar            info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) {
1127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK, freeBuffer(kPortIndexOutput, i));
1128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1134f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
1135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
1136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(info->mStatus == BufferInfo::OWNED_BY_US
1138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
1139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput && mNativeWindow != NULL
1141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && info->mStatus == BufferInfo::OWNED_BY_US) {
11423fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        cancelBufferToNativeWindow(info);
1143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(mOMX->freeBuffer(
1146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, portIndex, info->mBufferID),
1147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
1148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mBuffers[portIndex].removeAt(i);
1150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1154f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::findBufferByID(
1155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        uint32_t portIndex, IOMX::buffer_id bufferID,
1156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ssize_t *index) {
1157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
1158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
1159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mBufferID == bufferID) {
1161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (index != NULL) {
1162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                *index = i;
1163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
1165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
1169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
1171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
11735778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setComponentRole(
1174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        bool isEncoder, const char *mime) {
1175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    struct MimeToRole {
1176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime;
1177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *decoderRole;
1178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *encoderRole;
1179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
1180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const MimeToRole kMimeToRole[] = {
1182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG,
1183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.mp3", "audio_encoder.mp3" },
11842944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
11852944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp1", "audio_encoder.mp1" },
11862944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
11872944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp2", "audio_encoder.mp2" },
1188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_NB,
1189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrnb", "audio_encoder.amrnb" },
1190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_WB,
1191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrwb", "audio_encoder.amrwb" },
1192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AAC,
1193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.aac", "audio_encoder.aac" },
1194729de186450f78c099637e1fce743fe531862c52Andreas Huber        { MEDIA_MIMETYPE_AUDIO_VORBIS,
1195729de186450f78c099637e1fce743fe531862c52Andreas Huber            "audio_decoder.vorbis", "audio_encoder.vorbis" },
1196bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian        { MEDIA_MIMETYPE_AUDIO_OPUS,
1197bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian            "audio_decoder.opus", "audio_encoder.opus" },
1198c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_MLAW,
1199c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" },
1200c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_ALAW,
1201c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711alaw", "audio_encoder.g711alaw" },
1202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_AVC,
1203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.avc", "video_encoder.avc" },
12042472b1c0d63454e5d90a982bd6c555de6c3127bdRachad        { MEDIA_MIMETYPE_VIDEO_HEVC,
12052472b1c0d63454e5d90a982bd6c555de6c3127bdRachad            "video_decoder.hevc", "video_encoder.hevc" },
1206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_MPEG4,
1207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.mpeg4", "video_encoder.mpeg4" },
1208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_H263,
1209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.h263", "video_encoder.h263" },
121094705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP8,
121194705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp8", "video_encoder.vp8" },
121294705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP9,
121394705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp9", "video_encoder.vp9" },
1214ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        { MEDIA_MIMETYPE_AUDIO_RAW,
1215ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            "audio_decoder.raw", "audio_encoder.raw" },
12162f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        { MEDIA_MIMETYPE_AUDIO_FLAC,
12172f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            "audio_decoder.flac", "audio_encoder.flac" },
1218ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        { MEDIA_MIMETYPE_AUDIO_MSGSM,
1219ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen            "audio_decoder.gsm", "audio_encoder.gsm" },
1220774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu        { MEDIA_MIMETYPE_VIDEO_MPEG2,
1221774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu            "video_decoder.mpeg2", "video_encoder.mpeg2" },
122297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        { MEDIA_MIMETYPE_AUDIO_AC3,
122397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            "audio_decoder.ac3", "audio_encoder.ac3" },
12248a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        { MEDIA_MIMETYPE_AUDIO_EAC3,
12258a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            "audio_decoder.eac3", "audio_encoder.eac3" },
1226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
1227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const size_t kNumMimeToRole =
1229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
1230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    size_t i;
1232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (i = 0; i < kNumMimeToRole; ++i) {
1233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcasecmp(mime, kMimeToRole[i].mime)) {
1234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (i == kNumMimeToRole) {
12395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_UNSUPPORTED;
1240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    const char *role =
1243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        isEncoder ? kMimeToRole[i].encoderRole
1244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                  : kMimeToRole[i].decoderRole;
1245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (role != NULL) {
1247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_PARAM_COMPONENTROLETYPE roleParams;
1248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        InitOMXParams(&roleParams);
1249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        strncpy((char *)roleParams.cRole,
1251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                role, OMX_MAX_STRINGNAME_SIZE - 1);
1252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
1254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->setParameter(
1256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamStandardComponentRole,
1257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &roleParams, sizeof(roleParams));
1258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
12605ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("[%s] Failed to set standard component role '%s'.",
1261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 mComponentName.c_str(), role);
12625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
1264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
12665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
1268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
12705778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::configureCodec(
1271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime, const sp<AMessage> &msg) {
12725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t encoder;
12735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("encoder", &encoder)) {
12745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        encoder = false;
12755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1277e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    sp<AMessage> inputFormat = new AMessage();
12784e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    sp<AMessage> outputFormat = mNotify->dup(); // will use this for kWhatOutputFormatChanged
1279e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
12805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mIsEncoder = encoder;
1281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
12828db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu
12835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setComponentRole(encoder /* isEncoder */, mime);
12845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
12865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
12875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
12885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitRate = 0;
12902f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    // FLAC encoder doesn't need a bitrate, other encoders do
12912f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
12922f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            && !msg->findInt32("bitrate", &bitRate)) {
12935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
12945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
12955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1296d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    int32_t storeMeta;
1297d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (encoder
1298d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && msg->findInt32("store-metadata-in-buffers", &storeMeta)
1299d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && storeMeta != 0) {
1300d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE);
1301d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1302d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (err != OK) {
1303308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              ALOGE("[%s] storeMetaDataInBuffers (input) failed w/ err %d",
1304308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    mComponentName.c_str(), err);
1305d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1306308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              return err;
1307308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang          }
1308308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang      }
1309d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1310308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t prependSPSPPS = 0;
13113a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    if (encoder
13123a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
13133a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && prependSPSPPS != 0) {
13143a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        OMX_INDEXTYPE index;
13153a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        err = mOMX->getExtensionIndex(
13163a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                mNode,
13173a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                "OMX.google.android.index.prependSPSPPSToIDRFrames",
13183a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                &index);
13193a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
13203a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err == OK) {
13213a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            PrependSPSPPSToIDRFramesParams params;
13223a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            InitOMXParams(&params);
13233a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            params.bEnable = OMX_TRUE;
13243a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
13253a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            err = mOMX->setParameter(
13263a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                    mNode, index, &params, sizeof(params));
13273a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
13283a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
13293a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err != OK) {
13303a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            ALOGE("Encoder could not be configured to emit SPS/PPS before "
13313a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                  "IDR frames. (err %d)", err);
13323a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
13333a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            return err;
13343a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
13353a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    }
13363a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
1337308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // Only enable metadata mode on encoder output if encoder can prepend
1338308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // sps/pps to idr frames, since in metadata mode the bitstream is in an
1339308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // opaque handle, to which we don't have access.
1340308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t video = !strncasecmp(mime, "video/", 6);
13418db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    mIsVideo = video;
1342308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (encoder && video) {
1343308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS
1344308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && msg->findInt32("store-metadata-in-buffers-output", &storeMeta)
1345308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && storeMeta != 0);
1346308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1347308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, enable);
1348308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1349308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        if (err != OK) {
1350308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            ALOGE("[%s] storeMetaDataInBuffers (output) failed w/ err %d",
1351308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                mComponentName.c_str(), err);
1352308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = 0;
1353308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        } else {
1354308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = enable;
1355308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        }
1356a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
1357a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (!msg->findInt64(
1358a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    "repeat-previous-frame-after",
1359a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    &mRepeatFrameDelayUs)) {
1360a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            mRepeatFrameDelayUs = -1ll;
1361a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
136294ee4b708acfa941581160b267afb79192b1d816Chong Zhang
136394ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (!msg->findInt64("max-pts-gap-to-encoder", &mMaxPtsGapUs)) {
13642c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mMaxPtsGapUs = -1ll;
13652c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
13662c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
136737b2b389139ed638831e49708c947863eef631efRonghua Wu        if (!msg->findFloat("max-fps-to-encoder", &mMaxFps)) {
136837b2b389139ed638831e49708c947863eef631efRonghua Wu            mMaxFps = -1;
136937b2b389139ed638831e49708c947863eef631efRonghua Wu        }
137037b2b389139ed638831e49708c947863eef631efRonghua Wu
13712c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (!msg->findInt64("time-lapse", &mTimePerCaptureUs)) {
13722c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mTimePerCaptureUs = -1ll;
137394ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
137472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
137572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (!msg->findInt32(
137672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    "create-input-buffers-suspended",
137772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    (int32_t*)&mCreateInputBuffersSuspended)) {
137872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mCreateInputBuffersSuspended = false;
137972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
1380308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    }
1381308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
13823a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar    // NOTE: we only use native window for video decoders
1383054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    sp<RefBase> obj;
13840d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    bool haveNativeWindow = msg->findObject("native-window", &obj)
13853a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            && obj != NULL && video && !encoder;
1386054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mStoreMetaDataInOutputBuffers = false;
1387e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if (video && !encoder) {
1388e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        inputFormat->setInt32("adaptive-playback", false);
13891713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang
13901713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        int32_t usageProtected;
13911713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        if (msg->findInt32("protected", &usageProtected) && usageProtected) {
13921713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            if (!haveNativeWindow) {
13931713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang                ALOGE("protected output buffers must be sent to an ANativeWindow");
13941713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang                return PERMISSION_DENIED;
13951713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            }
13961713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            mFlags |= kFlagIsGrallocUsageProtected;
13971713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
13981713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        }
1399e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
14003a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar    if (haveNativeWindow) {
14011de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar        sp<ANativeWindow> nativeWindow =
14021de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar            static_cast<ANativeWindow *>(static_cast<Surface *>(obj.get()));
14035a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
14046597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        // START of temporary support for automatic FRC - THIS WILL BE REMOVED
14056597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        int32_t autoFrc;
14066597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        if (msg->findInt32("auto-frc", &autoFrc)) {
14076597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            bool enabled = autoFrc;
14086597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            OMX_CONFIG_BOOLEANTYPE config;
14096597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            InitOMXParams(&config);
14106597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            config.bEnabled = (OMX_BOOL)enabled;
14116597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            status_t temp = mOMX->setConfig(
14126597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                    mNode, (OMX_INDEXTYPE)OMX_IndexConfigAutoFramerateConversion,
14136597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                    &config, sizeof(config));
14146597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            if (temp == OK) {
14156597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                outputFormat->setInt32("auto-frc", enabled);
14166597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            } else if (enabled) {
14176597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                ALOGI("codec does not support requested auto-frc (err %d)", temp);
14186597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            }
14196597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        }
14206597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        // END of temporary support for automatic FRC
14216597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar
14225a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        int32_t tunneled;
14235a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        if (msg->findInt32("feature-tunneled-playback", &tunneled) &&
14245a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            tunneled != 0) {
14255a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            ALOGI("Configuring TUNNELED video playback.");
1426ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            mTunneled = true;
14275a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
142897827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad            int32_t audioHwSync = 0;
142997827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad            if (!msg->findInt32("audio-hw-sync", &audioHwSync)) {
14305a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGW("No Audio HW Sync provided for video tunnel");
14315a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            }
14325a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            err = configureTunneledVideoPlayback(audioHwSync, nativeWindow);
14335a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (err != OK) {
143497827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad                ALOGE("configureTunneledVideoPlayback(%d,%p) failed!",
14355a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        audioHwSync, nativeWindow.get());
14365a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                return err;
1437fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
1438fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1439d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            int32_t maxWidth = 0, maxHeight = 0;
1440d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            if (msg->findInt32("max-width", &maxWidth) &&
1441d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    msg->findInt32("max-height", &maxHeight)) {
1442d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad
1443d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                err = mOMX->prepareForAdaptivePlayback(
1444d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                        mNode, kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight);
1445d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                if (err != OK) {
1446d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    ALOGW("[%s] prepareForAdaptivePlayback failed w/ err %d",
1447d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                            mComponentName.c_str(), err);
14483a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    // allow failure
14493a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    err = OK;
1450d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                } else {
1451d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("max-width", maxWidth);
1452d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("max-height", maxHeight);
1453d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("adaptive-playback", true);
1454d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                }
1455d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            }
14565a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        } else {
1457ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            ALOGV("Configuring CPU controlled video playback.");
1458ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            mTunneled = false;
1459ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
14603fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // Explicity reset the sideband handle of the window for
14613fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // non-tunneled video in case the window was previously used
14623fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // for a tunneled video playback.
14633fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            err = native_window_set_sideband_stream(nativeWindow.get(), NULL);
14643fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            if (err != OK) {
14653fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad                ALOGE("set_sideband_stream(NULL) failed! (err %d).", err);
14663fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad                return err;
14673fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            }
14683fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad
14695a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            // Always try to enable dynamic output buffers on native surface
14705a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            err = mOMX->storeMetaDataInBuffers(
14715a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    mNode, kPortIndexOutput, OMX_TRUE);
14725a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (err != OK) {
14735a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d",
1474fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        mComponentName.c_str(), err);
1475e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
14765a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // if adaptive playback has been requested, try JB fallback
14775a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // NOTE: THIS FALLBACK MECHANISM WILL BE REMOVED DUE TO ITS
14785a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // LARGE MEMORY REQUIREMENT
14795a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
14805a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // we will not do adaptive playback on software accessed
14815a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // surfaces as they never had to respond to changes in the
14825a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // crop window, and we don't trust that they will be able to.
14835a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                int usageBits = 0;
14845a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                bool canDoAdaptivePlayback;
14855a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
14865a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                if (nativeWindow->query(
14875a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        nativeWindow.get(),
14885a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        NATIVE_WINDOW_CONSUMER_USAGE_BITS,
14895a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        &usageBits) != OK) {
14905a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    canDoAdaptivePlayback = false;
14915a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                } else {
14925a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    canDoAdaptivePlayback =
14935a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        (usageBits &
14945a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                                (GRALLOC_USAGE_SW_READ_MASK |
14955a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                                 GRALLOC_USAGE_SW_WRITE_MASK)) == 0;
14965a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                }
14975a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
14985a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                int32_t maxWidth = 0, maxHeight = 0;
14995a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                if (canDoAdaptivePlayback &&
15005a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        msg->findInt32("max-width", &maxWidth) &&
15015a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        msg->findInt32("max-height", &maxHeight)) {
15025a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    ALOGV("[%s] prepareForAdaptivePlayback(%dx%d)",
15035a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mComponentName.c_str(), maxWidth, maxHeight);
15045a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
15055a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    err = mOMX->prepareForAdaptivePlayback(
15065a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mNode, kPortIndexOutput, OMX_TRUE, maxWidth,
15075a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            maxHeight);
15085a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    ALOGW_IF(err != OK,
15095a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            "[%s] prepareForAdaptivePlayback failed w/ err %d",
15105a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mComponentName.c_str(), err);
15115a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
15125a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    if (err == OK) {
15135a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("max-width", maxWidth);
15145a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("max-height", maxHeight);
15155a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("adaptive-playback", true);
15165a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    }
1517e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
15185a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // allow failure
15195a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                err = OK;
15205a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            } else {
15215a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGV("[%s] storeMetaDataInBuffers succeeded",
15225a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        mComponentName.c_str());
15235a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                mStoreMetaDataInOutputBuffers = true;
15245a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                inputFormat->setInt32("adaptive-playback", true);
1525fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
15260167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber
15275a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            int32_t push;
15285a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (msg->findInt32("push-blank-buffers-on-shutdown", &push)
15295a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    && push != 0) {
15305a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
15315a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            }
15320167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        }
1533e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang
1534e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        int32_t rotationDegrees;
1535e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        if (msg->findInt32("rotation-degrees", &rotationDegrees)) {
1536e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            mRotationDegrees = rotationDegrees;
1537e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        } else {
1538e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            mRotationDegrees = 0;
1539e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        }
1540054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1541054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1542308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (video) {
15433a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // determine need for software renderer
15443a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        bool usingSwRenderer = false;
15453a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (haveNativeWindow && mComponentName.startsWith("OMX.google.")) {
15463a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            usingSwRenderer = true;
15473a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            haveNativeWindow = false;
15483a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
15493a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
15505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (encoder) {
15515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupVideoEncoder(mime, msg);
15525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
15530d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            err = setupVideoDecoder(mime, msg, haveNativeWindow);
15545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15553a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
15563a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (err != OK) {
15573a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            return err;
15583a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
15593a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
15603a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (haveNativeWindow) {
15611de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar            mNativeWindow = static_cast<Surface *>(obj.get());
15621de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar            CHECK(mNativeWindow != NULL);
15633a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
15643a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
15653a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // initialize native window now to get actual output format
15663a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // TODO: this is needed for some encoders even though they don't use native window
15673a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        CHECK_EQ((status_t)OK, initNativeWindow());
15683a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
15693a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // fallback for devices that do not handle flex-YUV for native buffers
15703a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (haveNativeWindow) {
15713a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            int32_t requestedColorFormat = OMX_COLOR_FormatUnused;
15723a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            if (msg->findInt32("color-format", &requestedColorFormat) &&
15733a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    requestedColorFormat == OMX_COLOR_FormatYUV420Flexible) {
15743a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                CHECK_EQ(getPortFormat(kPortIndexOutput, outputFormat), (status_t)OK);
15753a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                int32_t colorFormat = OMX_COLOR_FormatUnused;
15763a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                OMX_U32 flexibleEquivalent = OMX_COLOR_FormatUnused;
15773a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                CHECK(outputFormat->findInt32("color-format", &colorFormat));
15783a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                ALOGD("[%s] Requested output format %#x and got %#x.",
15793a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        mComponentName.c_str(), requestedColorFormat, colorFormat);
15803a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                if (!isFlexibleColorFormat(
15813a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                                mOMX, mNode, colorFormat, haveNativeWindow, &flexibleEquivalent)
15823a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        || flexibleEquivalent != (OMX_U32)requestedColorFormat) {
15833a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    // device did not handle flex-YUV request for native window, fall back
15843a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    // to SW renderer
15853a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    ALOGI("[%s] Falling back to software renderer", mComponentName.c_str());
15863a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    mNativeWindow.clear();
15873a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    haveNativeWindow = false;
15883a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    usingSwRenderer = true;
15893a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    if (mStoreMetaDataInOutputBuffers) {
15903a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, OMX_FALSE);
15913a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        mStoreMetaDataInOutputBuffers = false;
15923a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        // TODO: implement adaptive-playback support for bytebuffer mode.
15933a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        // This is done by SW codecs, but most HW codecs don't support it.
15943a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        inputFormat->setInt32("adaptive-playback", false);
15953a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
15963a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    if (err == OK) {
15973a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        err = mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
15983a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
15993a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    if (mFlags & kFlagIsGrallocUsageProtected) {
16003a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        // fallback is not supported for protected playback
16013a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        err = PERMISSION_DENIED;
16023a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    } else if (err == OK) {
16033a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        err = setupVideoDecoder(mime, msg, false);
16043a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
16053a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                }
16063a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            }
16073a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
16083a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
16093a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (usingSwRenderer) {
16103a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            outputFormat->setInt32("using-sw-renderer", 1);
16113a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
161242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
161342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        int32_t numChannels, sampleRate;
161442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        if (!msg->findInt32("channel-count", &numChannels)
161542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
161642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // Since we did not always check for these, leave them optional
161742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // and have the decoder figure it all out.
161842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = OK;
161942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        } else {
162042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = setupRawAudioFormat(
162142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    encoder ? kPortIndexInput : kPortIndexOutput,
162242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    sampleRate,
162342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    numChannels);
162442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        }
1625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
1626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t numChannels, sampleRate;
16275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)
16285778822d86b0337407514b9372562b86edfa91cdAndreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
16295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
16305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
1631aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            int32_t isADTS, aacProfile;
1632b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            int32_t sbrMode;
16338045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            int32_t maxOutputChannelCount;
16342965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            int32_t pcmLimiterEnable;
16358045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            drcParams_t drc;
1636ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            if (!msg->findInt32("is-adts", &isADTS)) {
1637ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                isADTS = 0;
1638ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
1639aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (!msg->findInt32("aac-profile", &aacProfile)) {
1640aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                aacProfile = OMX_AUDIO_AACObjectNull;
1641aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
1642b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            if (!msg->findInt32("aac-sbr-mode", &sbrMode)) {
1643b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                sbrMode = -1;
1644b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            }
1645ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
16468045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-max-output-channel_count", &maxOutputChannelCount)) {
16478045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                maxOutputChannelCount = -1;
16488045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
16492965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            if (!msg->findInt32("aac-pcm-limiter-enable", &pcmLimiterEnable)) {
16502965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                // value is unknown
16512965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                pcmLimiterEnable = -1;
16522965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            }
16538045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-encoded-target-level", &drc.encodedTargetLevel)) {
16548045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
16558045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.encodedTargetLevel = -1;
16568045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
16578045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-cut-level", &drc.drcCut)) {
16588045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
16598045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.drcCut = -1;
16608045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
16618045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-boost-level", &drc.drcBoost)) {
16628045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
16638045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.drcBoost = -1;
16648045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
16658045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-heavy-compression", &drc.heavyCompression)) {
16668045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
16678045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.heavyCompression = -1;
16688045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
16698045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-target-ref-level", &drc.targetRefLevel)) {
16708045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
16718045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.targetRefLevel = -1;
16728045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
16738045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi
1674ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            err = setupAACCodec(
16754471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    encoder, numChannels, sampleRate, bitRate, aacProfile,
16762965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                    isADTS != 0, sbrMode, maxOutputChannelCount, drc,
16772965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                    pcmLimiterEnable);
16785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
1679729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
16805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
1681729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
16825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
1683729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
1684729de186450f78c099637e1fce743fe531862c52Andreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
1685729de186450f78c099637e1fce743fe531862c52Andreas Huber        // These are PCM-like formats with a fixed sample rate but
1686729de186450f78c099637e1fce743fe531862c52Andreas Huber        // a variable number of channels.
1687729de186450f78c099637e1fce743fe531862c52Andreas Huber
1688729de186450f78c099637e1fce743fe531862c52Andreas Huber        int32_t numChannels;
16895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)) {
16905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
16915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
169217c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            int32_t sampleRate;
169317c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            if (!msg->findInt32("sample-rate", &sampleRate)) {
169417c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen                sampleRate = 8000;
169517c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            }
169617c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            err = setupG711Codec(encoder, sampleRate, numChannels);
16975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16982f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
1699ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        int32_t numChannels = 0, sampleRate = 0, compressionLevel = -1;
17002f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (encoder &&
17012f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                (!msg->findInt32("channel-count", &numChannels)
17022f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                        || !msg->findInt32("sample-rate", &sampleRate))) {
17032f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("missing channel count or sample rate for FLAC encoder");
17042f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            err = INVALID_OPERATION;
17052f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        } else {
17062f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            if (encoder) {
1707516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                if (!msg->findInt32(
1708cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                            "complexity", &compressionLevel) &&
1709cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                    !msg->findInt32(
1710516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                            "flac-compression-level", &compressionLevel)) {
1711cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                    compressionLevel = 5; // default FLAC compression level
17122f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel < 0) {
1713516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1714516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 0",
1715516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
17162f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 0;
17172f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel > 8) {
1718516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1719516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 8",
1720516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
17212f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 8;
17222f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                }
17232f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            }
1724516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            err = setupFlacCodec(
1725516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    encoder, numChannels, sampleRate, compressionLevel);
17262f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
1727ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
1728ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        int32_t numChannels, sampleRate;
1729ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        if (encoder
1730ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("channel-count", &numChannels)
1731ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
1732ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = INVALID_OPERATION;
1733ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        } else {
1734ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
1735ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        }
173697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AC3)) {
173797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t numChannels;
173897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t sampleRate;
173997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        if (!msg->findInt32("channel-count", &numChannels)
174097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                || !msg->findInt32("sample-rate", &sampleRate)) {
174197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = INVALID_OPERATION;
174297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        } else {
174397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = setupAC3Codec(encoder, numChannels, sampleRate);
174497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        }
17458a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_EAC3)) {
17468a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        int32_t numChannels;
17478a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        int32_t sampleRate;
17488a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        if (!msg->findInt32("channel-count", &numChannels)
17498a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                || !msg->findInt32("sample-rate", &sampleRate)) {
17508a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            err = INVALID_OPERATION;
17518a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        } else {
17528a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            err = setupEAC3Codec(encoder, numChannels, sampleRate);
17538a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        }
17545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1755729de186450f78c099637e1fce743fe531862c52Andreas Huber
17564471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    if (err != OK) {
17574471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber        return err;
17584471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    }
17594471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber
17608b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
17618b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderDelay = 0;
17628b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
17639806555d3930be43e11106281dee354820ac1c88Andreas Huber
17648b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
17658b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderPadding = 0;
17668b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
17678b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen
17689806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (msg->findInt32("channel-mask", &mChannelMask)) {
17699806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = true;
17709806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else {
17719806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = false;
17729806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
17739806555d3930be43e11106281dee354820ac1c88Andreas Huber
1774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t maxInputSize;
1775f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (msg->findInt32("max-input-size", &maxInputSize)) {
17765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
1777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
17785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
1779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
17805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17818b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    int32_t priority;
17828b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    if (msg->findInt32("priority", &priority)) {
17838b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu        err = setPriority(priority);
17848b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    }
17858b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu
1786ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    int32_t rateInt = -1;
1787ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    float rateFloat = -1;
1788ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (!msg->findFloat("operating-rate", &rateFloat)) {
1789ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        msg->findInt32("operating-rate", &rateInt);
1790ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        rateFloat = (float)rateInt;  // 16MHz (FLINTMAX) is OK for upper bound.
1791ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
1792ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (rateFloat > 0) {
1793ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        err = setOperatingRate(rateFloat, video);
1794ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
1795ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu
17964e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    mBaseOutputFormat = outputFormat;
17974e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar
1798e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ(getPortFormat(kPortIndexInput, inputFormat), (status_t)OK);
1799e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ(getPortFormat(kPortIndexOutput, outputFormat), (status_t)OK);
1800e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mInputFormat = inputFormat;
1801e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mOutputFormat = outputFormat;
1802e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
18035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
1804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
18068b806ea894ca098366629458bfdd1df4866afcdfRonghua Wustatus_t ACodec::setPriority(int32_t priority) {
18078b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    if (priority < 0) {
18088b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu        return BAD_VALUE;
18098b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    }
18108b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    OMX_PARAM_U32TYPE config;
18118b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    InitOMXParams(&config);
18128b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    config.nU32 = (OMX_U32)priority;
18138b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    status_t temp = mOMX->setConfig(
18148b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu            mNode, (OMX_INDEXTYPE)OMX_IndexConfigPriority,
18158b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu            &config, sizeof(config));
18168b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    if (temp != OK) {
18178b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu        ALOGI("codec does not support config priority (err %d)", temp);
18188b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    }
18198b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    return OK;
18208b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu}
18218b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu
1822ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wustatus_t ACodec::setOperatingRate(float rateFloat, bool isVideo) {
1823ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (rateFloat < 0) {
1824ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        return BAD_VALUE;
1825ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
1826ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    OMX_U32 rate;
1827ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (isVideo) {
1828ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        if (rateFloat > 65535) {
1829ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            return BAD_VALUE;
1830ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        }
1831ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        rate = (OMX_U32)(rateFloat * 65536.0f + 0.5f);
1832ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    } else {
1833ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        if (rateFloat > UINT_MAX) {
1834ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            return BAD_VALUE;
1835ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        }
1836ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        rate = (OMX_U32)(rateFloat);
1837ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
1838ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    OMX_PARAM_U32TYPE config;
1839ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    InitOMXParams(&config);
1840ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    config.nU32 = rate;
1841ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    status_t err = mOMX->setConfig(
1842ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            mNode, (OMX_INDEXTYPE)OMX_IndexConfigOperatingRate,
1843ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            &config, sizeof(config));
1844ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (err != OK) {
1845ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        ALOGI("codec does not support config operating rate (err %d)", err);
1846ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
1847ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    return OK;
1848ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu}
1849ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu
1850f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
1851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
1853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
1854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (def.nBufferSize >= size) {
1863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
1864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nBufferSize = size;
1867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
1869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->getParameter(
1876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(def.nBufferSize >= size);
1883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
18875778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::selectAudioPortFormat(
18885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
18895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_AUDIO_PARAM_PORTFORMATTYPE format;
18905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&format);
18915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    format.nPortIndex = portIndex;
18935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (OMX_U32 index = 0;; ++index) {
18945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        format.nIndex = index;
18955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
18975778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioPortFormat,
18985778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &format, sizeof(format));
18995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
19015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
19025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (format.eEncoding == desiredFormat) {
19055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
19105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format));
19115778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
19125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19135778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAACCodec(
1914aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        bool encoder, int32_t numChannels, int32_t sampleRate,
19158045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        int32_t bitRate, int32_t aacProfile, bool isADTS, int32_t sbrMode,
19162965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang        int32_t maxOutputChannelCount, const drcParams_t& drc,
19172965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang        int32_t pcmLimiterEnable) {
1918ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (encoder && isADTS) {
1919ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return -EINVAL;
1920ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
1921ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
19225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setupRawAudioFormat(
19235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
19245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sampleRate,
19255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            numChannels);
19265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (encoder) {
19325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
19335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
19355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
19365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
19395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
19405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = kPortIndexOutput;
19415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
19435778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
19445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
19465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
19475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.bFlagErrorConcealment = OMX_TRUE;
19505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
19515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
19535778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
19545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
19565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
19575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
19605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&profile);
19615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nPortIndex = kPortIndexOutput;
19625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
19645778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
19655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
19675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
19685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nChannels = numChannels;
19715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eChannelMode =
19735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (numChannels == 1)
19745778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
19755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nSampleRate = sampleRate;
19775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nBitRate = bitRate;
19785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAudioBandWidth = 0;
19795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nFrameLength = 0;
19805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACtools = OMX_AUDIO_AACToolAll;
19815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACERtools = OMX_AUDIO_AACERNone;
1982aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
19835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
1984b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        switch (sbrMode) {
1985b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 0:
1986b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // disable sbr
1987b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
1988b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
1989b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
1990b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 1:
1991b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable single-rate sbr
1992b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
1993b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
1994b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
1995b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 2:
1996b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable dual-rate sbr
1997b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
1998b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
1999b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2000b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case -1:
2001b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable both modes -> the codec will decide which mode should be used
2002b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
2003b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
2004b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2005b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        default:
2006b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // unsupported sbr mode
2007b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            return BAD_VALUE;
2008b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        }
2009b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi
20105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
20125778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
20135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
20155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
20165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_AUDIO_PARAM_AACPROFILETYPE profile;
2022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&profile);
2023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nPortIndex = kPortIndexInput;
2024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
20255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
2026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
2027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nChannels = numChannels;
2033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nSampleRate = sampleRate;
2034ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2035ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    profile.eAACStreamFormat =
2036ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        isADTS
2037ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            ? OMX_AUDIO_AACStreamFormatMP4ADTS
2038ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            : OMX_AUDIO_AACStreamFormatMP4FF;
2039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
20408045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    OMX_AUDIO_PARAM_ANDROID_AACPRESENTATIONTYPE presentation;
20418045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nMaxOutputChannels = maxOutputChannelCount;
20428045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nDrcCut = drc.drcCut;
20438045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nDrcBoost = drc.drcBoost;
20448045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nHeavyCompression = drc.heavyCompression;
20458045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nTargetReferenceLevel = drc.targetRefLevel;
20468045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nEncodedTargetLevel = drc.encodedTargetLevel;
20472965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang    presentation.nPCMLimiterEnable = pcmLimiterEnable;
20488045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi
20498045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    status_t res = mOMX->setParameter(mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
20508045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    if (res == OK) {
20518045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        // optional parameters, will not cause configuration failure
20528045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        mOMX->setParameter(mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAacPresentation,
20538045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                &presentation, sizeof(presentation));
20548045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    } else {
20558045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        ALOGW("did not set AudioAndroidAacPresentation due to error %d when setting AudioAac", res);
20568045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    }
20578045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    return res;
20585778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
2059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
206097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryustatus_t ACodec::setupAC3Codec(
206197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        bool encoder, int32_t numChannels, int32_t sampleRate) {
206297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    status_t err = setupRawAudioFormat(
206397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
206497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
206597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
206697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
206797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
206897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
206997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (encoder) {
207097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        ALOGW("AC3 encoding is not supported.");
207197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return INVALID_OPERATION;
207297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
207397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
207497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    OMX_AUDIO_PARAM_ANDROID_AC3TYPE def;
207597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    InitOMXParams(&def);
207697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nPortIndex = kPortIndexInput;
207797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
207897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    err = mOMX->getParameter(
207997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
208097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
208197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
208297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
208397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
208497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
208597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
208697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
208797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
208897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nChannels = numChannels;
208997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nSampleRate = sampleRate;
209097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
209197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    return mOMX->setParameter(
209297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
209397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
209497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
209597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
209697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu}
209797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
20988a4728966dc9c78e21c3c93a927707e93c05e5e0Rachadstatus_t ACodec::setupEAC3Codec(
20998a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        bool encoder, int32_t numChannels, int32_t sampleRate) {
21008a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    status_t err = setupRawAudioFormat(
21018a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
21028a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
21038a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (err != OK) {
21048a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return err;
21058a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
21068a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
21078a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (encoder) {
21088a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        ALOGW("EAC3 encoding is not supported.");
21098a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return INVALID_OPERATION;
21108a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
21118a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
21128a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    OMX_AUDIO_PARAM_ANDROID_EAC3TYPE def;
21138a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    InitOMXParams(&def);
21148a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nPortIndex = kPortIndexInput;
21158a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
21168a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    err = mOMX->getParameter(
21178a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            mNode,
21188a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
21198a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            &def,
21208a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            sizeof(def));
21218a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
21228a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (err != OK) {
21238a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return err;
21248a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
21258a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
21268a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nChannels = numChannels;
21278a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nSampleRate = sampleRate;
21288a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
21298a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    return mOMX->setParameter(
21308a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            mNode,
21318a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
21328a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            &def,
21338a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            sizeof(def));
21348a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad}
21358a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
21365778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
21375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        bool isAMRWB, int32_t bps) {
21385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (isAMRWB) {
21395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 6600) {
21405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB0;
21415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 8850) {
21425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB1;
21435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 12650) {
21445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB2;
21455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 14250) {
21465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB3;
21475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 15850) {
21485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB4;
21495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 18250) {
21505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB5;
21515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 19850) {
21525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB6;
21535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 23050) {
21545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB7;
21555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 23850 bps
21585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeWB8;
21595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {  // AMRNB
21605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 4750) {
21615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB0;
21625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5150) {
21635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB1;
21645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5900) {
21655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB2;
21665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 6700) {
21675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB3;
21685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7400) {
21695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB4;
21705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7950) {
21715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB5;
21725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 10200) {
21735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB6;
21745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 12200 bps
21775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeNB7;
21785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
21815778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
2182729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_AMRTYPE def;
2183729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
21845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
2185729de186450f78c099637e1fce743fe531862c52Andreas Huber
2186729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err =
2187729de186450f78c099637e1fce743fe531862c52Andreas Huber        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
2188729de186450f78c099637e1fce743fe531862c52Andreas Huber
2189729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2190729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2191729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2192729de186450f78c099637e1fce743fe531862c52Andreas Huber
2193729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
21945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
21955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
21975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
2198729de186450f78c099637e1fce743fe531862c52Andreas Huber
21995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2202729de186450f78c099637e1fce743fe531862c52Andreas Huber
22035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupRawAudioFormat(
22045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
22055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            isWAMR ? 16000 : 8000 /* sampleRate */,
22065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            1 /* numChannels */);
2207729de186450f78c099637e1fce743fe531862c52Andreas Huber}
2208729de186450f78c099637e1fce743fe531862c52Andreas Huber
220917c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissenstatus_t ACodec::setupG711Codec(bool encoder, int32_t sampleRate, int32_t numChannels) {
22105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(!encoder);  // XXX TODO
22115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2212729de186450f78c099637e1fce743fe531862c52Andreas Huber    return setupRawAudioFormat(
221317c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            kPortIndexInput, sampleRate, numChannels);
2214729de186450f78c099637e1fce743fe531862c52Andreas Huber}
2215729de186450f78c099637e1fce743fe531862c52Andreas Huber
22162f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivistatus_t ACodec::setupFlacCodec(
22172f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
22182f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
22192f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder) {
22202f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        OMX_AUDIO_PARAM_FLACTYPE def;
22212f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        InitOMXParams(&def);
22222f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nPortIndex = kPortIndexOutput;
22232f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
22242f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        // configure compression level
22252f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        status_t err = mOMX->getParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
22262f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
22272f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
22282f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
22292f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
22302f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nCompressionLevel = compressionLevel;
22312f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        err = mOMX->setParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
22322f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
22332f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
22342f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
22352f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
22362f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
22372f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
22382f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    return setupRawAudioFormat(
22392f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            encoder ? kPortIndexInput : kPortIndexOutput,
22402f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            sampleRate,
22412f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            numChannels);
22422f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi}
22432f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
2244729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t ACodec::setupRawAudioFormat(
2245729de186450f78c099637e1fce743fe531862c52Andreas Huber        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
2246729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
2247729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
2248729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.nPortIndex = portIndex;
2249729de186450f78c099637e1fce743fe531862c52Andreas Huber
2250729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err = mOMX->getParameter(
2251729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2252729de186450f78c099637e1fce743fe531862c52Andreas Huber
2253729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2254729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2255729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2256729de186450f78c099637e1fce743fe531862c52Andreas Huber
2257729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
2258729de186450f78c099637e1fce743fe531862c52Andreas Huber
2259729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->setParameter(
2260729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2261729de186450f78c099637e1fce743fe531862c52Andreas Huber
2262729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2263729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2264729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2265729de186450f78c099637e1fce743fe531862c52Andreas Huber
2266729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
2267729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&pcmParams);
2268729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nPortIndex = portIndex;
2269729de186450f78c099637e1fce743fe531862c52Andreas Huber
2270729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->getParameter(
2271729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
2272729de186450f78c099637e1fce743fe531862c52Andreas Huber
2273729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2274729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2275729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2276729de186450f78c099637e1fce743fe531862c52Andreas Huber
2277729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nChannels = numChannels;
2278729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.eNumData = OMX_NumericalDataSigned;
2279729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.bInterleaved = OMX_TRUE;
2280729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nBitPerSample = 16;
2281729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nSamplingRate = sampleRate;
2282729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
2283729de186450f78c099637e1fce743fe531862c52Andreas Huber
2284c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber    if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
2285c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber        return OMX_ErrorNone;
2286729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2287729de186450f78c099637e1fce743fe531862c52Andreas Huber
2288729de186450f78c099637e1fce743fe531862c52Andreas Huber    return mOMX->setParameter(
2289729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
2290729de186450f78c099637e1fce743fe531862c52Andreas Huber}
2291729de186450f78c099637e1fce743fe531862c52Andreas Huber
22925a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachadstatus_t ACodec::configureTunneledVideoPlayback(
229397827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad        int32_t audioHwSync, const sp<ANativeWindow> &nativeWindow) {
22945a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    native_handle_t* sidebandHandle;
22955a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
22965a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    status_t err = mOMX->configureVideoTunnelMode(
22975a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            mNode, kPortIndexOutput, OMX_TRUE, audioHwSync, &sidebandHandle);
22985a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    if (err != OK) {
22995a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        ALOGE("configureVideoTunnelMode failed! (err %d).", err);
23005a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        return err;
23015a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    }
23025a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
23035a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    err = native_window_set_sideband_stream(nativeWindow.get(), sidebandHandle);
23045a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    if (err != OK) {
23055a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        ALOGE("native_window_set_sideband_stream(%p) failed! (err %d).",
23065a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                sidebandHandle, err);
23075a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        return err;
23085a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    }
23095a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
23105a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    return OK;
23115a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad}
23125a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
2313f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoPortFormatType(
2314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
2315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_VIDEO_CODINGTYPE compressionFormat,
23160d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        OMX_COLOR_FORMATTYPE colorFormat,
23170d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        bool usingNativeBuffers) {
2318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
2319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
2320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = portIndex;
2321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
2322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool found = false;
2323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 index = 0;
2325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (;;) {
2326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        format.nIndex = index;
2327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->getParameter(
2328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamVideoPortFormat,
2329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &format, sizeof(format));
2330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
2332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return err;
2333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2335229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        // substitute back flexible color format to codec supported format
2336229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        OMX_U32 flexibleEquivalent;
23370d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (compressionFormat == OMX_VIDEO_CodingUnused
23380d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && isFlexibleColorFormat(
23390d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        mOMX, mNode, format.eColorFormat, usingNativeBuffers, &flexibleEquivalent)
23400d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && colorFormat == flexibleEquivalent) {
2341229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            ALOGI("[%s] using color format %#x in place of %#x",
2342229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                    mComponentName.c_str(), format.eColorFormat, colorFormat);
2343229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            colorFormat = format.eColorFormat;
2344229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
2345229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
2346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The following assertion is violated by TI's video decoder.
2347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // CHECK_EQ(format.nIndex, index);
2348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
2350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexInput
2351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && colorFormat == format.eColorFormat) {
2352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eCompressionFormat does not seem right.
2353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
2354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
2355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexOutput
2357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && compressionFormat == format.eCompressionFormat) {
2358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eColorFormat does not seem right.
2359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
2360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
2361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (format.eCompressionFormat == compressionFormat
2365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && format.eColorFormat == colorFormat) {
2366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            found = true;
2367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ++index;
2371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!found) {
2374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return UNKNOWN_ERROR;
2375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->setParameter(
2378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
2379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
2380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
2382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
23840d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// Set optimal output format. OMX component lists output formats in the order
23850d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// of preference, but this got more complicated since the introduction of flexible
23860d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// YUV formats. We support a legacy behavior for applications that do not use
23870d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// surface output, do not specify an output format, but expect a "usable" standard
23880d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// OMX format. SW readable and standard formats must be flex-YUV.
23890d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar//
23900d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// Suggested preference order:
23910d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal format for texture rendering (mediaplayer behavior)
23920d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal SW readable & texture renderable format (flex-YUV support)
23930d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal SW readable non-renderable format (flex-YUV bytebuffer support)
23940d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - legacy "usable" standard formats
23950d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar//
23960d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// For legacy support, we prefer a standard format, but will settle for a SW readable
23970d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// flex-YUV format.
23980d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnarstatus_t ACodec::setSupportedOutputFormat(bool getLegacyFlexibleFormat) {
23990d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    OMX_VIDEO_PARAM_PORTFORMATTYPE format, legacyFormat;
2400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
2401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = kPortIndexOutput;
2402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
24030d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    InitOMXParams(&legacyFormat);
24040d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    // this field will change when we find a suitable legacy format
24050d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    legacyFormat.eColorFormat = OMX_COLOR_FormatUnused;
2406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
24070d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    for (OMX_U32 index = 0; ; ++index) {
24080d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        format.nIndex = index;
24090d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        status_t err = mOMX->getParameter(
24100d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                mNode, OMX_IndexParamVideoPortFormat,
24110d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                &format, sizeof(format));
24120d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (err != OK) {
24130d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            // no more formats, pick legacy format if found
24140d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            if (legacyFormat.eColorFormat != OMX_COLOR_FormatUnused) {
24150d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                 memcpy(&format, &legacyFormat, sizeof(format));
24160d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                 break;
24170d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            }
24180d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            return err;
24190d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
24200d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (format.eCompressionFormat != OMX_VIDEO_CodingUnused) {
24210d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            return OMX_ErrorBadParameter;
24220d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
24230d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (!getLegacyFlexibleFormat) {
24240d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            break;
24250d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
24260d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        // standard formats that were exposed to users before
24270d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (format.eColorFormat == OMX_COLOR_FormatYUV420Planar
24280d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_COLOR_FormatYUV420PackedPlanar
24290d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar
24300d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_COLOR_FormatYUV420PackedSemiPlanar
24310d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar) {
24320d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            break;
24330d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
24340d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        // find best legacy non-standard format
24350d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        OMX_U32 flexibleEquivalent;
24360d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (legacyFormat.eColorFormat == OMX_COLOR_FormatUnused
24370d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && isFlexibleColorFormat(
24380d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        mOMX, mNode, format.eColorFormat, false /* usingNativeBuffers */,
24390d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        &flexibleEquivalent)
24400d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && flexibleEquivalent == OMX_COLOR_FormatYUV420Flexible) {
24410d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            memcpy(&legacyFormat, &format, sizeof(format));
24420d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
24430d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    }
2444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mOMX->setParameter(
2445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
2446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
2447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2449e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic const struct VideoCodingMapEntry {
2450e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    const char *mMime;
2451e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    OMX_VIDEO_CODINGTYPE mVideoCodingType;
2452e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber} kVideoCodingMapEntry[] = {
2453e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC },
24542472b1c0d63454e5d90a982bd6c555de6c3127bdRachad    { MEDIA_MIMETYPE_VIDEO_HEVC, OMX_VIDEO_CodingHEVC },
2455e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 },
2456e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 },
2457e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 },
245894705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 },
245994705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 },
2460e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber};
2461e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
24625778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic status_t GetVideoCodingTypeFromMime(
24635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
2464e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
2465e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
2466e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
2467e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) {
2468e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *codingType = kVideoCodingMapEntry[i].mVideoCodingType;
2469e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
2470e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
2471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2473e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    *codingType = OMX_VIDEO_CodingUnused;
2474e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2475e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
2476e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
2477e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2478e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic status_t GetMimeTypeForVideoCoding(
2479e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        OMX_VIDEO_CODINGTYPE codingType, AString *mime) {
2480e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
2481e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
2482e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
2483e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) {
2484e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *mime = kVideoCodingMapEntry[i].mMime;
2485e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
2486e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
2487e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
2488e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2489e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    mime->clear();
2490e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2491e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
24925778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
24935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24945778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoDecoder(
24950d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        const char *mime, const sp<AMessage> &msg, bool haveNativeWindow) {
249689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    int32_t width, height;
249789869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    if (!msg->findInt32("width", &width)
249889869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            || !msg->findInt32("height", &height)) {
249989869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        return INVALID_OPERATION;
250089869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    }
250189869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar
25025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
25035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
25045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
25065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
25075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
2510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
2511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
251689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    int32_t tmp;
251789869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    if (msg->findInt32("color-format", &tmp)) {
251889869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        OMX_COLOR_FORMATTYPE colorFormat =
251989869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            static_cast<OMX_COLOR_FORMATTYPE>(tmp);
252089869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        err = setVideoPortFormatType(
25210d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                kPortIndexOutput, OMX_VIDEO_CodingUnused, colorFormat, haveNativeWindow);
252289869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        if (err != OK) {
252389869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            ALOGW("[%s] does not support color format %d",
252489869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar                  mComponentName.c_str(), colorFormat);
25250d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            err = setSupportedOutputFormat(!haveNativeWindow /* getLegacyFlexibleFormat */);
252689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        }
252789869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    } else {
25280d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        err = setSupportedOutputFormat(!haveNativeWindow /* getLegacyFlexibleFormat */);
252989869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    }
2530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
253578b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    int32_t frameRateInt;
253678b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    float frameRateFloat;
253778b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    if (!msg->findFloat("frame-rate", &frameRateFloat)) {
253878b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        if (!msg->findInt32("frame-rate", &frameRateInt)) {
253978b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            frameRateInt = -1;
254078b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        }
254178b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        frameRateFloat = (float)frameRateInt;
254278b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    }
254378b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad
2544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
254578b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            kPortIndexInput, width, height, compressionFormat, frameRateFloat);
2546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
2552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
2553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
25615778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) {
25625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
25635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("color-format", &tmp)) {
25645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
25655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_COLOR_FORMATTYPE colorFormat =
25685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        static_cast<OMX_COLOR_FORMATTYPE>(tmp);
25695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setVideoPortFormatType(
25715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
25725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
25745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support color format %d",
25755778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str(), colorFormat);
25765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
25785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Input port configuration */
25815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
25835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&def);
25845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
25865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexInput;
25885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
25905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
25915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
25935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
25945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t width, height, bitrate;
25975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("width", &width)
25985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("height", &height)
25995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("bitrate", &bitrate)) {
26005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
26015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
26045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
26055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t stride;
26075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("stride", &stride)) {
26085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        stride = width;
26095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nStride = stride;
26125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t sliceHeight;
26145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("slice-height", &sliceHeight)) {
26155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sliceHeight = height;
26165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nSliceHeight = sliceHeight;
26195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
26215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
26235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
26245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
26255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
26265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
26275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
26285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
26292c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        mTimePerFrameUs = (int64_t) (1000000.0f / frameRate);
26305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
26335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
2634a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    // this is redundant as it was already set up in setVideoPortFormatType
2635a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    // FIXME for now skip this only for flexible YUV formats
2636a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    if (colorFormat != OMX_COLOR_FormatYUV420Flexible) {
2637a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar        video_def->eColorFormat = colorFormat;
2638a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    }
26395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
26415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
26425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
26445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set input port definition parameters.",
26455778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
26465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
26485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Output port configuration */
26515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
26535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
26545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
26565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
26575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
26605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
26615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
26635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support compression format %d",
26645778822d86b0337407514b9372562b86edfa91cdAndreas Huber             mComponentName.c_str(), compressionFormat);
26655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
26675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexOutput;
26705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
26725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
26735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
26755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
26765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
26795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
26805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = 0;
26815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nBitrate = bitrate;
26825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = compressionFormat;
26835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = OMX_COLOR_FormatUnused;
26845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
26865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
26875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
26895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set output port definition parameters.",
26905778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
26915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
26935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (compressionFormat) {
26965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingMPEG4:
26975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupMPEG4EncoderParameters(msg);
26985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
26995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingH263:
27015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupH263EncoderParameters(msg);
27025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
27035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingAVC:
27055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupAVCEncoderParameters(msg);
27065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
27075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2708c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        case OMX_VIDEO_CodingHEVC:
2709c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            err = setupHEVCEncoderParameters(msg);
2710c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            break;
2711c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
271289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP8:
271389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP9:
271489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            err = setupVPXEncoderParameters(msg);
271589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            break;
271689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
27175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
27185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
27195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2721d36a023778256f0550e9a09e9993c066e8a3c7d7Ronghua Wu    if (err == OK) {
2722d36a023778256f0550e9a09e9993c066e8a3c7d7Ronghua Wu        ALOGI("setupVideoEncoder succeeded");
2723d36a023778256f0550e9a09e9993c066e8a3c7d7Ronghua Wu    }
27245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
27265778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
27275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27280dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dongstatus_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) {
27290dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    OMX_VIDEO_PARAM_INTRAREFRESHTYPE params;
27300dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    InitOMXParams(&params);
27310dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.nPortIndex = kPortIndexOutput;
27320dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
27330dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode);
27340dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
27350dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic ||
27360dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
27370dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
27380dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) {
27390dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
27400dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
27410dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nCirMBs = mbs;
27420dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
27430dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
27440dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive ||
27450dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
27460dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
27470dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) {
27480dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
27490dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
27500dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirMBs = mbs;
27510dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
27520dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t ref;
27530dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) {
27540dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
27550dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
27560dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirRef = ref;
27570dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
27580dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
27590dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = mOMX->setParameter(
27600dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            mNode, OMX_IndexParamVideoIntraRefresh,
27610dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            &params, sizeof(params));
27620dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    return err;
27630dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong}
27640dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
27655778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
27665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (iFramesInterval < 0) {
27675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0xFFFFFFFF;
27685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (iFramesInterval == 0) {
27695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0;
27705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_U32 ret = frameRate * iFramesInterval;
27725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return ret;
27735778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
27745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
277596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatic OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) {
277696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    int32_t tmp;
277796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    if (!msg->findInt32("bitrate-mode", &tmp)) {
277896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        return OMX_Video_ControlRateVariable;
277996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    }
278096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
278196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp);
278296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber}
278396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
27845778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
27855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
27865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
27875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
27885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
27895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
279196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
279296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
27935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
27945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
27955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
27965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
27975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
27985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
27995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
28005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
28035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&mpeg4type);
28045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPortIndex = kPortIndexOutput;
28055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
28075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
28085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
28105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
28115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nSliceHeaderSpacing = 0;
28145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bSVH = OMX_FALSE;
28155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bGov = OMX_FALSE;
28165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nAllowedPictureTypes =
28185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
28195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
28215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mpeg4type.nPFrames == 0) {
28225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
28235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nBFrames = 0;
28255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nIDCVLCThreshold = 0;
28265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bACPred = OMX_TRUE;
28275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nMaxPacketSize = 256;
28285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nTimeIncRes = 1000;
28295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nHeaderExtension = 0;
28305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bReversibleVLC = OMX_FALSE;
28315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
28335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
28345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
28355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
28365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
28375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
28385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
28405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
28425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
28435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
28445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
28465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
28475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
28505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
28515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
28535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
28545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
285696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
28575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
28595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
28605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
28635778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
28645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28655778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
28665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
28675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
28685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
28695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
28705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
287296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
287396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
28745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
28755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
28765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
28775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
28785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
28795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
28805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
28815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_H263TYPE h263type;
28845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h263type);
28855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPortIndex = kPortIndexOutput;
28865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
28885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
28895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
28915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
28925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nAllowedPictureTypes =
28955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
28965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
28985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h263type.nPFrames == 0) {
28995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
29005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nBFrames = 0;
29025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
29045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
29055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
29065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
29075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
29085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
29095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
29115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
29135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
29145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
29155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
29175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
29185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bPLUSPTYPEAllowed = OMX_FALSE;
29215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bForceRoundingTypeToZero = OMX_FALSE;
29225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPictureHeaderRepetition = 0;
29235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nGOBHeaderInterval = 0;
29245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
29265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
29275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
29295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
29305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
293296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
29335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
29355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
29365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
29395778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
29405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2941a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar// static
2942a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnarint /* OMX_VIDEO_AVCLEVELTYPE */ ACodec::getAVCLevelFor(
2943a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        int width, int height, int rate, int bitrate,
2944a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        OMX_VIDEO_AVCPROFILETYPE profile) {
2945a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    // convert bitrate to main/baseline profile kbps equivalent
2946a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    switch (profile) {
2947a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        case OMX_VIDEO_AVCProfileHigh10:
2948a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 3000); break;
2949a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        case OMX_VIDEO_AVCProfileHigh:
2950a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 1250); break;
2951a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        default:
2952a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 1000); break;
2953a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    }
2954a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
2955a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    // convert size and rate to MBs
2956a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    width = divUp(width, 16);
2957a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    height = divUp(height, 16);
2958a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    int mbs = width * height;
2959a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    rate *= mbs;
2960a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    int maxDimension = max(width, height);
2961a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
2962a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    static const int limits[][5] = {
2963a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        /*   MBps     MB   dim  bitrate        level */
2964a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    1485,    99,  28,     64, OMX_VIDEO_AVCLevel1  },
2965a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    1485,    99,  28,    128, OMX_VIDEO_AVCLevel1b },
2966a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    3000,   396,  56,    192, OMX_VIDEO_AVCLevel11 },
2967a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    6000,   396,  56,    384, OMX_VIDEO_AVCLevel12 },
2968a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   11880,   396,  56,    768, OMX_VIDEO_AVCLevel13 },
2969a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   11880,   396,  56,   2000, OMX_VIDEO_AVCLevel2  },
2970a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   19800,   792,  79,   4000, OMX_VIDEO_AVCLevel21 },
2971a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   20250,  1620, 113,   4000, OMX_VIDEO_AVCLevel22 },
2972a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   40500,  1620, 113,  10000, OMX_VIDEO_AVCLevel3  },
2973a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  108000,  3600, 169,  14000, OMX_VIDEO_AVCLevel31 },
2974a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  216000,  5120, 202,  20000, OMX_VIDEO_AVCLevel32 },
2975a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  245760,  8192, 256,  20000, OMX_VIDEO_AVCLevel4  },
2976a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  245760,  8192, 256,  50000, OMX_VIDEO_AVCLevel41 },
2977a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  522240,  8704, 263,  50000, OMX_VIDEO_AVCLevel42 },
2978a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  589824, 22080, 420, 135000, OMX_VIDEO_AVCLevel5  },
2979a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  983040, 36864, 543, 240000, OMX_VIDEO_AVCLevel51 },
2980a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        { 2073600, 36864, 543, 240000, OMX_VIDEO_AVCLevel52 },
2981a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    };
2982a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
2983a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    for (size_t i = 0; i < ARRAY_SIZE(limits); i++) {
2984a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        const int (&limit)[5] = limits[i];
2985a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        if (rate <= limit[0] && mbs <= limit[1] && maxDimension <= limit[2]
2986a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar                && bitrate <= limit[3]) {
2987a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            return limit[4];
2988a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        }
2989a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    }
2990a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    return 0;
2991a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar}
2992a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
29935778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
29945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
29955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
29965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
29975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
29985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
300096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
300196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
30025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
30035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
30045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
30055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
30065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
30075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
30085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
30095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
30105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30110dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = OK;
30120dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    int32_t intraRefreshMode = 0;
30130dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) {
30140dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode);
30150dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (err != OK) {
30160dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
30170dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong                    err, intraRefreshMode);
30180dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return err;
30190dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
30200dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
30210dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
30225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_AVCTYPE h264type;
30235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h264type);
30245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nPortIndex = kPortIndexOutput;
30255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30260dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    err = mOMX->getParameter(
30275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
30285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
30305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
30315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
30325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nAllowedPictureTypes =
30345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
30355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
30375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
30385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
30395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
30405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
30415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
30425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
30445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
30465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
30475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
30485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
30505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
30515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
30525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // XXX
30547c25df82dfc8bbedb58608242f0d923a4594bb14James Dong    if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) {
30557c25df82dfc8bbedb58608242f0d923a4594bb14James Dong        ALOGW("Use baseline profile instead of %d for AVC recording",
30567c25df82dfc8bbedb58608242f0d923a4594bb14James Dong            h264type.eProfile);
30575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
30585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
30595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
30615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nSliceHeaderSpacing = 0;
30625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bUseHadamard = OMX_TRUE;
30635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefFrames = 1;
30645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nBFrames = 0;
30655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
30665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (h264type.nPFrames == 0) {
30675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
30685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
30695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx10ActiveMinus1 = 0;
30705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx11ActiveMinus1 = 0;
30715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bEntropyCodingCABAC = OMX_FALSE;
30725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bWeightedPPrediction = OMX_FALSE;
30735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bconstIpred = OMX_FALSE;
30745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirect8x8Inference = OMX_FALSE;
30755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirectSpatialTemporal = OMX_FALSE;
30765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nCabacInitIdc = 0;
30775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
30785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.nBFrames != 0) {
30805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
30815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
30825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableUEP = OMX_FALSE;
30845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableFMO = OMX_FALSE;
30855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableASO = OMX_FALSE;
30865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableRS = OMX_FALSE;
30875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bFrameMBsOnly = OMX_TRUE;
30885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bMBAFF = OMX_FALSE;
30895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
30905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
30925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
30935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
30955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
30965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
30975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
309896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return configureBitrate(bitrate, bitrateMode);
30995778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
31005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3101c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachadstatus_t ACodec::setupHEVCEncoderParameters(const sp<AMessage> &msg) {
3102c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    int32_t bitrate, iFrameInterval;
3103c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findInt32("bitrate", &bitrate)
3104c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
3105c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return INVALID_OPERATION;
3106c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
3107c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3108c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
3109c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3110c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    float frameRate;
3111c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findFloat("frame-rate", &frameRate)) {
3112c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t tmp;
3113c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("frame-rate", &tmp)) {
3114c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
3115c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
3116c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        frameRate = (float)tmp;
3117c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
3118c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3119c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_PARAM_HEVCTYPE hevcType;
3120c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    InitOMXParams(&hevcType);
3121c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    hevcType.nPortIndex = kPortIndexOutput;
3122c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3123c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    status_t err = OK;
3124c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    err = mOMX->getParameter(
3125c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
3126c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
3127c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
3128c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
3129c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3130c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    int32_t profile;
3131c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (msg->findInt32("profile", &profile)) {
3132c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t level;
3133c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("level", &level)) {
3134c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
3135c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
3136c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3137c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        err = verifySupportForProfileAndLevel(profile, level);
3138c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (err != OK) {
3139c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return err;
3140c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
3141c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3142c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eProfile = static_cast<OMX_VIDEO_HEVCPROFILETYPE>(profile);
3143c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eLevel = static_cast<OMX_VIDEO_HEVCLEVELTYPE>(level);
3144c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
3145c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3146c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    // TODO: Need OMX structure definition for setting iFrameInterval
3147c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3148c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    err = mOMX->setParameter(
3149c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
3150c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
3151c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
3152c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
3153c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3154c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    return configureBitrate(bitrate, bitrateMode);
3155c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad}
3156c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
315789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huberstatus_t ACodec::setupVPXEncoderParameters(const sp<AMessage> &msg) {
315889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    int32_t bitrate;
31594154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    int32_t iFrameInterval = 0;
31604154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    size_t tsLayers = 0;
31614154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE pattern =
31624154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        OMX_VIDEO_VPXTemporalLayerPatternNone;
31634154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    static const uint32_t kVp8LayerRateAlloction
31644154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS]
31654154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS] = {
31664154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        {100, 100, 100},  // 1 layer
31674154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 60, 100, 100},  // 2 layers {60%, 40%}
31684154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 40,  60, 100},  // 3 layers {40%, 20%, 40%}
31694154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    };
317089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    if (!msg->findInt32("bitrate", &bitrate)) {
317189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        return INVALID_OPERATION;
317289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    }
31734154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    msg->findInt32("i-frame-interval", &iFrameInterval);
317489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
317589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
317689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
31774154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    float frameRate;
31784154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (!msg->findFloat("frame-rate", &frameRate)) {
31794154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        int32_t tmp;
31804154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (!msg->findInt32("frame-rate", &tmp)) {
31814154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            return INVALID_OPERATION;
31824154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
31834154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        frameRate = (float)tmp;
31844154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
31854154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
31864154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    AString tsSchema;
31874154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (msg->findString("ts-schema", &tsSchema)) {
31884154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (tsSchema == "webrtc.vp8.1-layer") {
31894154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
31904154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 1;
31914154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else if (tsSchema == "webrtc.vp8.2-layer") {
31924154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
31934154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 2;
31944154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else if (tsSchema == "webrtc.vp8.3-layer") {
31954154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
31964154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 3;
31974154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else {
31984154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            ALOGW("Unsupported ts-schema [%s]", tsSchema.c_str());
31994154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
32004154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
32014154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
32024154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
32034154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    InitOMXParams(&vp8type);
32044154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    vp8type.nPortIndex = kPortIndexOutput;
32054154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    status_t err = mOMX->getParameter(
32064154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
32074154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            &vp8type, sizeof(vp8type));
32084154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
32094154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (err == OK) {
32104154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (iFrameInterval > 0) {
32114154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nKeyFrameInterval = setPFramesSpacing(iFrameInterval, frameRate);
32124154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
32134154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.eTemporalPattern = pattern;
32144154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.nTemporalLayerCount = tsLayers;
32154154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (tsLayers > 0) {
32164154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            for (size_t i = 0; i < OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS; i++) {
32174154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                vp8type.nTemporalLayerBitrateRatio[i] =
32184154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                    kVp8LayerRateAlloction[tsLayers - 1][i];
32194154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            }
32204154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
32214154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (bitrateMode == OMX_Video_ControlRateConstant) {
32224154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMinQuantizer = 2;
32234154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMaxQuantizer = 63;
32244154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
32254154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
32264154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        err = mOMX->setParameter(
32274154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
32284154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                &vp8type, sizeof(vp8type));
32294154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (err != OK) {
32304154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            ALOGW("Extended VP8 parameters set failed: %d", err);
32314154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
32324154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
32334154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
323489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    return configureBitrate(bitrate, bitrateMode);
323589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber}
323689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
32375778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::verifySupportForProfileAndLevel(
32385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t profile, int32_t level) {
32395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
32405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&params);
32415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    params.nPortIndex = kPortIndexOutput;
32425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (params.nProfileIndex = 0;; ++params.nProfileIndex) {
32445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
32455778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode,
32465778822d86b0337407514b9372562b86edfa91cdAndreas Huber                OMX_IndexParamVideoProfileLevelQuerySupported,
32475778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &params,
32485778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sizeof(params));
32495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
32515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
32525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
32535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
32555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
32565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (profile == supportedProfile && level <= supportedLevel) {
32585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OK;
32595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
32605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
32615778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
32625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
326396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatus_t ACodec::configureBitrate(
326496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) {
32655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
32665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&bitrateType);
32675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
32685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
32705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
32715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
32725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
32745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
32755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
32765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
327796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    bitrateType.eControlRate = bitrateMode;
32785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nTargetBitrate = bitrate;
32795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
32815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
32825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
32835778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
32845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32855778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupErrorCorrectionParameters() {
32865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
32875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&errorCorrectionType);
32885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nPortIndex = kPortIndexOutput;
32895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
32915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
32925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
32935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
32955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OK;  // Optional feature. Ignore this failure
32965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
32975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableHEC = OMX_FALSE;
32995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableResync = OMX_TRUE;
33005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nResynchMarkerSpacing = 256;
33015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
33025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableRVLC = OMX_FALSE;
33035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
33055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
33065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
33075778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
33085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3309f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoFormatOnPort(
3310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
331178b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat,
331278b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        float frameRate) {
3313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
3314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
3315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
3316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
3318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
3320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
3321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
3323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
3325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // XXX Need a (much) better heuristic to compute input buffer sizes.
3326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const size_t X = 64 * 1024;
3327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (def.nBufferSize < X) {
3328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.nBufferSize = X;
3329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
3333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameWidth = width;
3335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameHeight = height;
3336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
3338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eCompressionFormat = compressionFormat;
3339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eColorFormat = OMX_COLOR_FormatUnused;
334078b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        if (frameRate >= 0) {
334178b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
334278b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        }
3343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
3346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
3347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
3349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3351f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::initNativeWindow() {
3352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL) {
3353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
3354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
3357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
3358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3360d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Hubersize_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
3361d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    size_t n = 0;
3362d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
3363d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
3364d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        const BufferInfo &info = mBuffers[portIndex].itemAt(i);
3365d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
3366d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
3367d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            ++n;
3368d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        }
3369d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    }
3370d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
3371d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    return n;
3372d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber}
3373d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
33747e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubersize_t ACodec::countBuffersOwnedByNativeWindow() const {
33757e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    size_t n = 0;
33767e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
33777e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
33787e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
33797e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
33807e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
33817e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            ++n;
33827e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        }
33837e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
33847e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
33857e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    return n;
33867e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
33877e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
33887e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubervoid ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
33897e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (mNativeWindow == NULL) {
33907e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        return;
33917e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
33927e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
3393e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    while (countBuffersOwnedByNativeWindow() > mNumUndequeuedBuffers
33947e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            && dequeueBufferFromNativeWindow() != NULL) {
3395c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        // these buffers will be submitted as regular buffers; account for this
3396c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        if (mStoreMetaDataInOutputBuffers && mMetaDataBuffersToSubmit > 0) {
3397c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar            --mMetaDataBuffersToSubmit;
3398c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        }
33997e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
34007e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
34017e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
3402f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs(
3403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
3404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
3405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
3406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus != BufferInfo::OWNED_BY_US
3408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3409609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGV("[%s] Buffer %u on port %u still has status %d",
3410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mComponentName.c_str(),
3411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info->mBufferID, portIndex, info->mStatus);
3412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
3413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3419f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs() {
3420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return allYourBuffersAreBelongToUs(kPortIndexInput)
3421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        && allYourBuffersAreBelongToUs(kPortIndexOutput);
3422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3424f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::deferMessage(const sp<AMessage> &msg) {
3425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.push_back(msg);
3426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3428f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::processDeferredMessages() {
3429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> > queue = mDeferredQueue;
3430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.clear();
3431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> >::iterator it = queue.begin();
3433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while (it != queue.end()) {
3434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        onMessageReceived(*it++);
3435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
343803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar// static
3439229d242665c612fd97431d1e7ac004823b47f181Lajos Molnarbool ACodec::describeDefaultColorFormat(DescribeColorFormatParams &params) {
344003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    MediaImage &image = params.sMediaImage;
344103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    memset(&image, 0, sizeof(image));
344203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
344303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mType = MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
344403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mNumPlanes = 0;
344503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
344603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    const OMX_COLOR_FORMATTYPE fmt = params.eColorFormat;
344703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mWidth = params.nFrameWidth;
344803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mHeight = params.nFrameHeight;
344903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
345003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    // only supporting YUV420
345103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    if (fmt != OMX_COLOR_FormatYUV420Planar &&
345203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        fmt != OMX_COLOR_FormatYUV420PackedPlanar &&
345303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        fmt != OMX_COLOR_FormatYUV420SemiPlanar &&
34545a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        fmt != OMX_COLOR_FormatYUV420PackedSemiPlanar &&
34555a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        fmt != HAL_PIXEL_FORMAT_YV12) {
345603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        ALOGW("do not know color format 0x%x = %d", fmt, fmt);
3457229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return false;
345803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    }
345903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
3460b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    // TEMPORARY FIX for some vendors that advertise sliceHeight as 0
3461b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    if (params.nStride != 0 && params.nSliceHeight == 0) {
3462b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        ALOGW("using sliceHeight=%u instead of what codec advertised (=0)",
3463b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar                params.nFrameHeight);
3464b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        params.nSliceHeight = params.nFrameHeight;
3465b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    }
3466b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar
3467b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    // we need stride and slice-height to be non-zero
3468b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    if (params.nStride == 0 || params.nSliceHeight == 0) {
3469b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        ALOGW("cannot describe color format 0x%x = %d with stride=%u and sliceHeight=%u",
3470b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar                fmt, fmt, params.nStride, params.nSliceHeight);
3471b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        return false;
3472b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    }
3473b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar
347403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    // set-up YUV format
347503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mType = MediaImage::MEDIA_IMAGE_TYPE_YUV;
347603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mNumPlanes = 3;
347703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mBitDepth = 8;
347803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mOffset = 0;
347903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mColInc = 1;
348003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mRowInc = params.nStride;
348103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mHorizSubsampling = 1;
348203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mVertSubsampling = 1;
348303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
34845a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar    switch ((int)fmt) {
34855a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        case HAL_PIXEL_FORMAT_YV12:
34865a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            if (params.bUsingNativeBuffers) {
34875a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                size_t ystride = align(params.nStride, 16);
34885a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                size_t cstride = align(params.nStride / 2, 16);
34895a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.Y].mRowInc = ystride;
34905a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
34915a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mOffset = ystride * params.nSliceHeight;
34925a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mColInc = 1;
34935a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mRowInc = cstride;
34945a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mHorizSubsampling = 2;
34955a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mVertSubsampling = 2;
34965a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
34975a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mOffset = image.mPlane[image.V].mOffset
34985a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                        + (cstride * params.nSliceHeight / 2);
34995a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mColInc = 1;
35005a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mRowInc = cstride;
35015a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mHorizSubsampling = 2;
35025a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mVertSubsampling = 2;
35035a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                break;
35045a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            } else {
35055a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                // fall through as YV12 is used for YUV420Planar by some codecs
35065a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            }
35075a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
35085a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        case OMX_COLOR_FormatYUV420Planar:
350903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420PackedPlanar:
351003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight;
351103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mColInc = 1;
351203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mRowInc = params.nStride / 2;
351303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mHorizSubsampling = 2;
351403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mVertSubsampling = 2;
351503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
351603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset
351703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    + (params.nStride * params.nSliceHeight / 4);
351803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mColInc = 1;
351903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mRowInc = params.nStride / 2;
352003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mHorizSubsampling = 2;
352103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mVertSubsampling = 2;
352203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            break;
352303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
352403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420SemiPlanar:
352503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            // FIXME: NV21 for sw-encoder, NV12 for decoder and hw-encoder
352603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420PackedSemiPlanar:
352703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            // NV12
352803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight;
352903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mColInc = 2;
353003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mRowInc = params.nStride;
353103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mHorizSubsampling = 2;
353203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mVertSubsampling = 2;
353303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
353403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset + 1;
353503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mColInc = 2;
353603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mRowInc = params.nStride;
353703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mHorizSubsampling = 2;
353803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mVertSubsampling = 2;
353903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            break;
354003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
354103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        default:
354203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            TRESPASS();
354303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    }
3544229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    return true;
3545229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar}
3546229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3547229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar// static
3548229d242665c612fd97431d1e7ac004823b47f181Lajos Molnarbool ACodec::describeColorFormat(
3549229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        const sp<IOMX> &omx, IOMX::node_id node,
3550229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        DescribeColorFormatParams &describeParams)
3551229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar{
3552229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    OMX_INDEXTYPE describeColorFormatIndex;
3553229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    if (omx->getExtensionIndex(
3554229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            node, "OMX.google.android.index.describeColorFormat",
3555229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            &describeColorFormatIndex) != OK ||
3556229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        omx->getParameter(
3557229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            node, describeColorFormatIndex,
3558229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            &describeParams, sizeof(describeParams)) != OK) {
3559229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return describeDefaultColorFormat(describeParams);
3560229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    }
3561229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    return describeParams.sMediaImage.mType !=
3562229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
3563229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar}
3564229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3565229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar// static
3566229d242665c612fd97431d1e7ac004823b47f181Lajos Molnarbool ACodec::isFlexibleColorFormat(
3567229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar         const sp<IOMX> &omx, IOMX::node_id node,
35680d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar         uint32_t colorFormat, bool usingNativeBuffers, OMX_U32 *flexibleEquivalent) {
3569229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    DescribeColorFormatParams describeParams;
3570229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    InitOMXParams(&describeParams);
3571229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.eColorFormat = (OMX_COLOR_FORMATTYPE)colorFormat;
3572229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    // reasonable dummy values
3573229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nFrameWidth = 128;
3574229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nFrameHeight = 128;
3575229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nStride = 128;
3576229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nSliceHeight = 128;
35770d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    describeParams.bUsingNativeBuffers = (OMX_BOOL)usingNativeBuffers;
3578229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3579229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    CHECK(flexibleEquivalent != NULL);
3580229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3581229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    if (!describeColorFormat(omx, node, describeParams)) {
3582229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return false;
3583229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    }
3584229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3585229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    const MediaImage &img = describeParams.sMediaImage;
3586229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    if (img.mType == MediaImage::MEDIA_IMAGE_TYPE_YUV) {
3587229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        if (img.mNumPlanes != 3 ||
3588229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            img.mPlane[img.Y].mHorizSubsampling != 1 ||
3589229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            img.mPlane[img.Y].mVertSubsampling != 1) {
3590229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            return false;
3591229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
3592229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3593229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        // YUV 420
3594229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        if (img.mPlane[img.U].mHorizSubsampling == 2
3595229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.U].mVertSubsampling == 2
3596229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.V].mHorizSubsampling == 2
3597229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.V].mVertSubsampling == 2) {
3598229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            // possible flexible YUV420 format
3599229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            if (img.mBitDepth <= 8) {
3600229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar               *flexibleEquivalent = OMX_COLOR_FormatYUV420Flexible;
3601229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar               return true;
3602229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            }
3603229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
3604229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    }
3605229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    return false;
360603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar}
360703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
3608e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarstatus_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> &notify) {
3609e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    // TODO: catch errors an return them instead of using CHECK
361031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
361131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    InitOMXParams(&def);
3612e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    def.nPortIndex = portIndex;
361331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
361431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ(mOMX->getParameter(
361531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)),
361631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber             (status_t)OK);
361731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3618e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ((int)def.eDir,
3619e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            (int)(portIndex == kPortIndexOutput ? OMX_DirOutput : OMX_DirInput));
362031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
362131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    switch (def.eDomain) {
362231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainVideo:
362331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
362431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
3625e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            switch ((int)videoDef->eCompressionFormat) {
3626e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_VIDEO_CodingUnused:
3627e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3628e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(mIsEncoder ^ (portIndex == kPortIndexOutput));
3629e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
3630e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3631e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("stride", videoDef->nStride);
3632e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("slice-height", videoDef->nSliceHeight);
3633e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("color-format", videoDef->eColorFormat);
3634e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
36350d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                    if (mNativeWindow == NULL) {
36360d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        DescribeColorFormatParams describeParams;
36370d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        InitOMXParams(&describeParams);
36380d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.eColorFormat = videoDef->eColorFormat;
36390d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nFrameWidth = videoDef->nFrameWidth;
36400d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nFrameHeight = videoDef->nFrameHeight;
36410d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nStride = videoDef->nStride;
36420d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nSliceHeight = videoDef->nSliceHeight;
36430d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.bUsingNativeBuffers = OMX_FALSE;
36440d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar
36450d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        if (describeColorFormat(mOMX, mNode, describeParams)) {
36460d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                            notify->setBuffer(
36470d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                    "image-data",
36480d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                    ABuffer::CreateAsCopy(
36490d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                            &describeParams.sMediaImage,
36500d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                            sizeof(describeParams.sMediaImage)));
36515a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
36525a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                            MediaImage *img = &describeParams.sMediaImage;
36535a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                            ALOGV("[%s] MediaImage { F(%zux%zu) @%zu+%zu+%zu @%zu+%zu+%zu @%zu+%zu+%zu }",
36545a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                                    mComponentName.c_str(), img->mWidth, img->mHeight,
36555a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                                    img->mPlane[0].mOffset, img->mPlane[0].mColInc, img->mPlane[0].mRowInc,
36565a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                                    img->mPlane[1].mOffset, img->mPlane[1].mColInc, img->mPlane[1].mRowInc,
36575a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                                    img->mPlane[2].mOffset, img->mPlane[2].mColInc, img->mPlane[2].mRowInc);
36580d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        }
365903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    }
366003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
366191a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                    if (portIndex != kPortIndexOutput) {
366291a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                        // TODO: also get input crop
366391a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                        break;
366491a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                    }
366591a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar
3666e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_CONFIG_RECTTYPE rect;
3667e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&rect);
366891a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                    rect.nPortIndex = portIndex;
3669e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3670e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    if (mOMX->getConfig(
367191a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                mNode,
367291a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                (portIndex == kPortIndexOutput ?
367391a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                        OMX_IndexConfigCommonOutputCrop :
367491a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                        OMX_IndexConfigCommonInputCrop),
3675e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &rect, sizeof(rect)) != OK) {
3676e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nLeft = 0;
3677e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nTop = 0;
3678e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nWidth = videoDef->nFrameWidth;
3679e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nHeight = videoDef->nFrameHeight;
3680e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    }
368131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3682e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nLeft, 0);
3683e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nTop, 0);
3684e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nWidth, 0u);
3685e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nHeight, 0u);
3686e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_LE(rect.nLeft + rect.nWidth - 1, videoDef->nFrameWidth);
3687e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_LE(rect.nTop + rect.nHeight - 1, videoDef->nFrameHeight);
3688e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3689e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setRect(
3690577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            "crop",
3691577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nLeft,
3692577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nTop,
3693e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                            rect.nLeft + rect.nWidth - 1,
3694e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                            rect.nTop + rect.nHeight - 1);
3695e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3696e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3697e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
36984730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
36994730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP8:
37004730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP9:
37014730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                {
37024730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
37034730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    InitOMXParams(&vp8type);
37044730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    vp8type.nPortIndex = kPortIndexOutput;
37054730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    status_t err = mOMX->getParameter(
37064730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            mNode,
37074730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
37084730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            &vp8type,
37094730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            sizeof(vp8type));
37104730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
37114730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    if (err == OK) {
37124730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        AString tsSchema = "none";
37134730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        if (vp8type.eTemporalPattern
37144730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                == OMX_VIDEO_VPXTemporalLayerPatternWebRTC) {
37154730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            switch (vp8type.nTemporalLayerCount) {
37164730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 1:
37174730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
37184730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.1-layer";
37194730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
37204730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
37214730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 2:
37224730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
37234730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.2-layer";
37244730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
37254730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
37264730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 3:
37274730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
37284730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.3-layer";
37294730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
37304730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
37314730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                default:
37324730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
37334730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
37344730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
37354730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            }
37364730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        }
37374730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        notify->setString("ts-schema", tsSchema);
37384730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    }
37394730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    // Fall through to set up mime.
37404730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                }
37414730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
3742e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                default:
3743e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3744e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(mIsEncoder ^ (portIndex == kPortIndexInput));
3745e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    AString mime;
3746e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    if (GetMimeTypeForVideoCoding(
3747e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        videoDef->eCompressionFormat, &mime) != OK) {
3748e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", "application/octet-stream");
3749e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    } else {
3750e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", mime.c_str());
3751e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    }
3752e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3753e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
375431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            }
3755e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("width", videoDef->nFrameWidth);
3756e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("height", videoDef->nFrameHeight);
37575a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            ALOGV("[%s] %s format is %s", mComponentName.c_str(),
37585a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                    portIndex == kPortIndexInput ? "input" : "output",
37595a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                    notify->debugString().c_str());
37605a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
376131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
376231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
376331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
376431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainAudio:
376531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
376631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
376731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
376897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            switch ((int)audioDef->eEncoding) {
3769e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingPCM:
3770e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3771e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_PCMMODETYPE params;
3772e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3773e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3774e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3775e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3776e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioPcm,
3777e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3778e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3779e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
378014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_GT(params.nChannels, 0);
3781e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK(params.nChannels == 1 || params.bInterleaved);
3782e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(params.nBitPerSample, 16u);
378314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
378414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.eNumData,
378514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_NumericalDataSigned);
378614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
378714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.ePCMMode,
378814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_AUDIO_PCMModeLinear);
3789e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3790e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
3791e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
3792e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSamplingRate);
3793e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3794e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mChannelMaskPresent) {
3795e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("channel-mask", mChannelMask);
37968b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                    }
3797e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
37988b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                }
37999806555d3930be43e11106281dee354820ac1c88Andreas Huber
3800e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAAC:
3801e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3802e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AACPROFILETYPE params;
3803e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3804e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3805e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3806e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3807e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAac,
3808e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3809e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3810e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3811e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
3812e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
3813e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
3814e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
3815e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
3816e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3817e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAMR:
3818e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3819e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AMRTYPE params;
3820e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3821e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
38229806555d3930be43e11106281dee354820ac1c88Andreas Huber
3823e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3824e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAmr,
3825e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3826e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3827e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3828e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", 1);
3829e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) {
3830e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
3831e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_WB);
3832e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3833e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 16000);
3834e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    } else {
3835e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
3836e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
3837e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3838e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 8000);
3839e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
3840e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
3841e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
3842e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3843e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingFLAC:
3844e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3845e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_FLACTYPE params;
3846e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3847e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3848e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3849e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3850e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioFlac,
3851e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3852e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3853e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3854e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC);
3855e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
3856e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
3857e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
3858e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
3859e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3860e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingMP3:
3861e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3862e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_MP3TYPE params;
3863e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
3864e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3865e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3866e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_EQ(mOMX->getParameter(
3867e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                mNode, OMX_IndexParamAudioMp3,
3868e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &params, sizeof(params)),
3869e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                             (status_t)OK);
3870e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3871e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MPEG);
3872e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
3873e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
3874e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3875e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
3876e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3877e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingVORBIS:
3878e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3879e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_VORBISTYPE params;
3880e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
3881e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3882e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3883e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_EQ(mOMX->getParameter(
3884e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                mNode, OMX_IndexParamAudioVorbis,
3885e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &params, sizeof(params)),
3886e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                             (status_t)OK);
3887e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3888e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_VORBIS);
3889e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
3890e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
3891e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3892e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
3893e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
389497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                case OMX_AUDIO_CodingAndroidAC3:
389597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                {
389697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    OMX_AUDIO_PARAM_ANDROID_AC3TYPE params;
389797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    InitOMXParams(&params);
3898e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
389997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
390097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    CHECK_EQ((status_t)OK, mOMX->getParameter(
390197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            mNode,
390297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
390397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            &params,
390497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            sizeof(params)));
390597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
390697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AC3);
390797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("channel-count", params.nChannels);
390897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("sample-rate", params.nSampleRate);
390997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    break;
391097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                }
3911e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
39128a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                case OMX_AUDIO_CodingAndroidEAC3:
39138a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                {
39148a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    OMX_AUDIO_PARAM_ANDROID_EAC3TYPE params;
39158a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    InitOMXParams(&params);
39168a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    params.nPortIndex = portIndex;
39178a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
39188a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    CHECK_EQ((status_t)OK, mOMX->getParameter(
39198a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                            mNode,
39208a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
39218a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                            &params,
39228a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                            sizeof(params)));
39238a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
39248a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_EAC3);
39258a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setInt32("channel-count", params.nChannels);
39268a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setInt32("sample-rate", params.nSampleRate);
39278a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    break;
39288a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                }
39298a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
39308c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                case OMX_AUDIO_CodingAndroidOPUS:
39318c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                {
39328c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    OMX_AUDIO_PARAM_ANDROID_OPUSTYPE params;
39338c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    InitOMXParams(&params);
39348c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    params.nPortIndex = portIndex;
39358c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
39368c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    CHECK_EQ((status_t)OK, mOMX->getParameter(
39378c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            mNode,
39388c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus,
39398c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            &params,
39408c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            sizeof(params)));
39418c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
39428c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_OPUS);
39438c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("channel-count", params.nChannels);
39448c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("sample-rate", params.nSampleRate);
39458c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    break;
39468c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                }
39478c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
394810d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                case OMX_AUDIO_CodingG711:
394910d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                {
395010d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    OMX_AUDIO_PARAM_PCMMODETYPE params;
395110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    InitOMXParams(&params);
395210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    params.nPortIndex = portIndex;
395310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
395410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    CHECK_EQ((status_t)OK, mOMX->getParameter(
395510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                            mNode,
395610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                            (OMX_INDEXTYPE)OMX_IndexParamAudioPcm,
395710d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                            &params,
395810d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                            sizeof(params)));
395910d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
396010d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    const char *mime = NULL;
396110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    if (params.ePCMMode == OMX_AUDIO_PCMModeMULaw) {
396210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_G711_MLAW;
396310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    } else if (params.ePCMMode == OMX_AUDIO_PCMModeALaw) {
396410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_G711_ALAW;
396510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    } else { // params.ePCMMode == OMX_AUDIO_PCMModeLinear
396610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_RAW;
396710d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    }
396810d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setString("mime", mime);
396910d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setInt32("channel-count", params.nChannels);
397010d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setInt32("sample-rate", params.nSamplingRate);
397110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    break;
397210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                }
397341d3f579d2c166984958263533284209b90c87d5Marco Nelissen
397441d3f579d2c166984958263533284209b90c87d5Marco Nelissen                case OMX_AUDIO_CodingGSMFR:
397541d3f579d2c166984958263533284209b90c87d5Marco Nelissen                {
397641d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    OMX_AUDIO_PARAM_MP3TYPE params;
397741d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    InitOMXParams(&params);
397841d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    params.nPortIndex = portIndex;
397941d3f579d2c166984958263533284209b90c87d5Marco Nelissen
398041d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    CHECK_EQ(mOMX->getParameter(
398141d3f579d2c166984958263533284209b90c87d5Marco Nelissen                                mNode, OMX_IndexParamAudioPcm,
398241d3f579d2c166984958263533284209b90c87d5Marco Nelissen                                &params, sizeof(params)),
398341d3f579d2c166984958263533284209b90c87d5Marco Nelissen                             (status_t)OK);
398441d3f579d2c166984958263533284209b90c87d5Marco Nelissen
398541d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MSGSM);
398641d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    notify->setInt32("channel-count", params.nChannels);
398741d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    notify->setInt32("sample-rate", params.nSampleRate);
398841d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    break;
398910d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                }
399010d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
3991e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                default:
3992e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    ALOGE("UNKNOWN AUDIO CODING: %d\n", audioDef->eEncoding);
3993e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    TRESPASS();
3994e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
399531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
399631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
399731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
399831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        default:
399931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            TRESPASS();
400031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    }
400131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4002e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    return OK;
4003e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar}
4004e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4005e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarvoid ACodec::sendFormatChange(const sp<AMessage> &reply) {
40064e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    sp<AMessage> notify = mBaseOutputFormat->dup();
4007e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    notify->setInt32("what", kWhatOutputFormatChanged);
4008e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4009e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ(getPortFormat(kPortIndexOutput, notify), (status_t)OK);
4010e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4011e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    AString mime;
4012e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK(notify->findString("mime", &mime));
4013e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4014e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    int32_t left, top, right, bottom;
4015e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if (mime == MEDIA_MIMETYPE_VIDEO_RAW &&
4016e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        mNativeWindow != NULL &&
4017e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->findRect("crop", &left, &top, &right, &bottom)) {
4018e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        // notify renderer of the crop change
4019e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        // NOTE: native window uses extended right-bottom coordinate
4020e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        reply->setRect("crop", left, top, right + 1, bottom + 1);
4021e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    } else if (mime == MEDIA_MIMETYPE_AUDIO_RAW &&
4022e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar               (mEncoderDelay || mEncoderPadding)) {
4023e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        int32_t channelCount;
4024e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        CHECK(notify->findInt32("channel-count", &channelCount));
4025e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        size_t frameSize = channelCount * sizeof(int16_t);
4026e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        if (mSkipCutBuffer != NULL) {
4027e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            size_t prevbufsize = mSkipCutBuffer->size();
4028e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            if (prevbufsize != 0) {
4029ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                ALOGW("Replacing SkipCutBuffer holding %zu bytes", prevbufsize);
4030e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            }
4031e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        }
4032e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        mSkipCutBuffer = new SkipCutBuffer(
4033e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                mEncoderDelay * frameSize,
4034e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                mEncoderPadding * frameSize);
4035e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
4036e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
403731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->post();
403831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
403931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mSentFormat = true;
404031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber}
404131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
40425778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
4043cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    sp<AMessage> notify = mNotify->dup();
4044d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatError);
4045251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    ALOGE("signalError(omxError %#x, internalError %d)", error, internalError);
4046251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
4047251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (internalError == UNKNOWN_ERROR) { // find better error code
4048251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        const status_t omxStatus = statusFromOMXError(error);
4049251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        if (omxStatus != 0) {
4050251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            internalError = omxStatus;
4051251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        } else {
4052251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            ALOGW("Invalid OMX error %#x", error);
4053251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        }
4054251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
40555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("err", internalError);
4056251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    notify->setInt32("actionCode", ACTION_CODE_FATAL); // could translate from OMX error.
4057cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->post();
4058cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber}
4059cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber
4060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4062eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberACodec::PortDescription::PortDescription() {
4063eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
4064eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4065496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t ACodec::requestIDRFrame() {
4066496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    if (!mIsEncoder) {
4067496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        return ERROR_UNSUPPORTED;
4068496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    }
4069496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4070496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    OMX_CONFIG_INTRAREFRESHVOPTYPE params;
4071496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    InitOMXParams(&params);
4072496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4073496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.nPortIndex = kPortIndexOutput;
4074496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.IntraRefreshVOP = OMX_TRUE;
4075496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4076496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    return mOMX->setConfig(
4077496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            mNode,
4078496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            OMX_IndexConfigVideoIntraVOPRefresh,
4079496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            &params,
4080496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            sizeof(params));
4081496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
4082496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4083eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubervoid ACodec::PortDescription::addBuffer(
4084eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        IOMX::buffer_id id, const sp<ABuffer> &buffer) {
4085eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBufferIDs.push_back(id);
4086eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBuffers.push_back(buffer);
4087eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
4088eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4089eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersize_t ACodec::PortDescription::countBuffers() {
4090eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.size();
4091eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
4092eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4093eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberIOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const {
4094eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.itemAt(index);
4095eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
4096eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4097eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const {
4098eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBuffers.itemAt(index);
4099eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
4100eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4101eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber////////////////////////////////////////////////////////////////////////////////
4102eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4103f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
4104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : AState(parentState),
4105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mCodec(codec) {
4106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4108ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas HuberACodec::BaseState::PortMode ACodec::BaseState::getPortMode(
4109ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
4110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return KEEP_BUFFERS;
4111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4113f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
4114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatInputBufferFilled:
4116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onInputBufferFilled(msg);
4118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatOutputBufferDrained:
4122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onOutputBufferDrained(msg);
4124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatOMXMessage:
4128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXMessage(msg);
4130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
41321dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        case ACodec::kWhatSetSurface:
41331dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        {
41341dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            sp<AReplyToken> replyID;
41351dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            CHECK(msg->senderAwaitsResponse(&replyID));
41361dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
41371dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            sp<RefBase> obj;
41381dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            CHECK(msg->findObject("surface", &obj));
41391dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
41401dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            status_t err = mCodec->handleSetSurface(static_cast<Surface *>(obj.get()));
41411dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
41421dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            sp<AMessage> response = new AMessage;
41431dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            response->setInt32("err", err);
41441dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            response->postReply(replyID);
41451dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            break;
41461dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
41471dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
41487cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
4149d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        case ACodec::kWhatUsePersistentInputSurface:
41507cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
41517cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
4152251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            // This may result in an app illegal state exception.
41537cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            ALOGE("Message 0x%x was not handled", msg->what());
41547cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
41557cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            return true;
41567cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
41577cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4158ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        case ACodec::kWhatOMXDied:
4159ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        {
4160251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            // This will result in kFlagSawMediaServerDie handling in MediaCodec.
4161ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            ALOGE("OMX/mediaserver died, signalling error!");
4162ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT);
4163ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            break;
4164ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        }
4165ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
416630358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        case ACodec::kWhatReleaseCodecInstance:
416730358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        {
416830358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            ALOGI("[%s] forcing the release of codec",
416930358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar                    mCodec->mComponentName.c_str());
417030358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            status_t err = mCodec->mOMX->freeNode(mCodec->mNode);
417130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            ALOGE_IF("[%s] failed to release codec instance: err=%d",
417230358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar                       mCodec->mComponentName.c_str(), err);
417330358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            sp<AMessage> notify = mCodec->mNotify->dup();
417430358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
417530358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            notify->post();
417630358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            break;
417730358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        }
417830358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar
4179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
4181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4186f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
4187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t type;
4188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findInt32("type", &type));
4189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
41905e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // there is a possibility that this is an outstanding message for a
41915e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // codec that we have already destroyed
4192ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    if (mCodec->mNode == 0) {
41935e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar        ALOGI("ignoring message as already freed component: %s",
41945e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar                msg->debugString().c_str());
41955e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar        return true;
41965e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    }
41975e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar
4198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::node_id nodeID;
4199609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("node", (int32_t*)&nodeID));
4200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(nodeID, mCodec->mNode);
4201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (type) {
4203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EVENT:
4204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t event, data1, data2;
4206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("event", &event));
4207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data1", &data1));
4208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data2", &data2));
4209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
42100af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            if (event == OMX_EventCmdComplete
42110af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data1 == OMX_CommandFlush
42120af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data2 == (int32_t)OMX_ALL) {
42130af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // Use of this notification is not consistent across
42140af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // implementations. We'll drop this notification and rely
42150af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // on flush-complete notifications on the individual port
42160af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // indices instead.
42170af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
42180af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                return true;
42190af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            }
42200af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
4221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEvent(
4222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_EVENTTYPE>(event),
4223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data1),
4224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data2));
4225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EMPTY_BUFFER_DONE:
4228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
4230609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
4231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEmptyBufferDone(bufferID);
4233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::FILL_BUFFER_DONE:
4236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
4238609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
4239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t rangeOffset, rangeLength, flags;
4241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs;
4242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_offset", &rangeOffset));
4244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_length", &rangeLength));
4245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("flags", &flags));
4246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt64("timestamp", &timeUs));
4247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXFillBufferDone(
4249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    bufferID,
4250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (size_t)rangeOffset, (size_t)rangeLength,
4251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (OMX_U32)flags,
4252784e24e386b088c05d653ab482f2e95cb53e3d01Andy Hung                    timeUs);
4253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
4257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4261f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEvent(
4262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (event != OMX_EventError) {
4264ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        ALOGV("[%s] EVENT(%d, 0x%08x, 0x%08x)",
4265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mCodec->mComponentName.c_str(), event, data1, data2);
4266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return false;
4268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4270ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGE("[%s] ERROR(0x%08x)", mCodec->mComponentName.c_str(), data1);
4271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4272251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // verify OMX component sends back an error we expect.
4273251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    OMX_ERRORTYPE omxError = (OMX_ERRORTYPE)data1;
4274251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (!isOMXError(omxError)) {
4275251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        ALOGW("Invalid OMX error %#x", omxError);
4276251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        omxError = OMX_ErrorUndefined;
4277251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
4278251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    mCodec->signalError(omxError);
4279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4283f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID) {
4284ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGV("[%s] onOMXEmptyBufferDone %u",
4285349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber         mCodec->mComponentName.c_str(), bufferID);
4286349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
4288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexInput, bufferID);
4289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
4291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
4292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
429396e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // We're in "store-metadata-in-buffers" mode, the underlying
429496e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // OMX component had access to data that's implicitly refcounted
429596e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // by this "MediaBuffer" object. Now that the OMX component has
429696e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // told us that it's done with the input buffer, we can decrement
429796e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // the mediaBuffer's reference count.
429896e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    info->mData->setMediaBufferBase(NULL);
4299d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
4301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            postFillThisBuffer(info);
4308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
4313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();  // Not currently used
4314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4321f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
4322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
4323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
4324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
4327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
4329d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatFillThisBuffer);
4330609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    notify->setInt32("buffer-id", info->mBufferID);
4331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mData->meta()->clear();
43332d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    notify->setBuffer("buffer", info->mData);
4334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
43351d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec);
4336609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    reply->setInt32("buffer-id", info->mBufferID);
4337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setMessage("reply", reply);
4339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->post();
4341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
4343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4345f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
4346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
4347609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
43482d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    sp<ABuffer> buffer;
4349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t err = OK;
43505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool eos = false;
4351a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar    PortMode mode = getPortMode(kPortIndexInput);
43525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
43532d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    if (!msg->findBuffer("buffer", &buffer)) {
4354a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar        /* these are unfilled buffers returned by client */
4355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findInt32("err", &err));
4356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
43577fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        if (err == OK) {
43587fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            /* buffers with no errors are returned on MediaCodec.flush */
43597fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            mode = KEEP_BUFFERS;
43607fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        } else {
43617fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            ALOGV("[%s] saw error %d instead of an input buffer",
43627fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                 mCodec->mComponentName.c_str(), err);
43637fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            eos = true;
43647fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        }
43653831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
43662d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber        buffer.clear();
4367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
43695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
43705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
43715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
43725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = ERROR_END_OF_STREAM;
43735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
43745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
4376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_UPSTREAM);
4377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
4379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
43835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (eos) {
4384dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (!mCodec->mPortEOS[kPortIndexInput]) {
4385dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
4386dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mInputEOSResult = err;
4387dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
4388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
43945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
4395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int64_t timeUs;
4396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
4397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
4399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t isCSD;
4401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
4402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
4403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
4404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
44055778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (eos) {
44065778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    flags |= OMX_BUFFERFLAG_EOS;
44075778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
44085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer != info->mData) {
4410ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] Needs to copy input data for buffer %u. (%p != %p)",
4411d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(),
4412d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         bufferID,
4413d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         buffer.get(), info->mData.get());
4414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    CHECK_LE(buffer->size(), info->mData->capacity());
4416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    memcpy(info->mData->data(), buffer->data(), buffer->size());
4417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
4418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4419078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
4420ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] calling emptyBuffer %u w/ codec specific data",
4421078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID);
44225778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else if (flags & OMX_BUFFERFLAG_EOS) {
4423ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] calling emptyBuffer %u w/ EOS",
44245778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str(), bufferID);
4425078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                } else {
4426d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
4427ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGI("[%s] calling emptyBuffer %u w/ time %lld us",
4428ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                         mCodec->mComponentName.c_str(), bufferID, (long long)timeUs);
4429d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#else
4430ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] calling emptyBuffer %u w/ time %lld us",
4431ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                         mCodec->mComponentName.c_str(), bufferID, (long long)timeUs);
4432d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
4433078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                }
4434349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4435d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
4436d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ACodec::BufferStats stats;
4437d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
4438d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mFillBufferDoneTimeUs = -1ll;
4439d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mCodec->mBufferStats.add(timeUs, stats);
4440d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
4441d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4442054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                if (mCodec->mStoreMetaDataInOutputBuffers) {
4443054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    // try to submit an output buffer for each input buffer
4444054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    PortMode outputMode = getPortMode(kPortIndexOutput);
4445054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4446054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    ALOGV("MetaDataBuffersToSubmit=%u portMode=%s",
4447054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            mCodec->mMetaDataBuffersToSubmit,
4448054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            (outputMode == FREE_BUFFERS ? "FREE" :
4449054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                             outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
4450054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    if (outputMode == RESUBMIT_BUFFERS) {
4451e53350373ac516257b4f8956ff1e3f1ac48f607eLajos Molnar                        mCodec->submitOutputMetaDataBuffer();
4452054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    }
4453054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                }
4454054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
4456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
4457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
4458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
4459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            buffer->size(),
4460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            flags,
4461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            timeUs),
4462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
44665778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (!eos) {
44675778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    getMoreInputDataIfPossible();
44685778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
44695778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] Signalled EOS on the input port",
44705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str());
44715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
44725778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
44735778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mInputEOSResult = err;
44745778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
4475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
4476dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (err != ERROR_END_OF_STREAM) {
44773856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port "
4478dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         "due to error %d",
4479dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str(), err);
4480dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                } else {
44813856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port",
4482dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str());
4483dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
4484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4485ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                ALOGV("[%s] calling emptyBuffer %u signalling EOS",
4486349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                     mCodec->mComponentName.c_str(), bufferID);
4487349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
4489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
4490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
4491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
4492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
4493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_BUFFERFLAG_EOS,
4494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0),
4495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexInput] = true;
4500dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                mCodec->mInputEOSResult = err;
4501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4504625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih
4505625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih        default:
4506625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
4507625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih            break;
4508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4511f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::getMoreInputDataIfPossible() {
4512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
4513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
4514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *eligible = NULL;
4517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
4519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
4520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
4522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
4523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // There's already a "read" pending.
4524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
4525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
4527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_US) {
4529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            eligible = info;
4530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (eligible == NULL) {
4534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
4535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(eligible);
4538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4540f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXFillBufferDone(
4541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferID,
4542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        size_t rangeOffset, size_t rangeLength,
4543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 flags,
4544784e24e386b088c05d653ab482f2e95cb53e3d01Andy Hung        int64_t timeUs) {
4545609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] onOMXFillBufferDone %u time %" PRId64 " us, flags = 0x%08x",
45465778822d86b0337407514b9372562b86edfa91cdAndreas Huber         mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
4547349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
4549d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4550d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
4551d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    index = mCodec->mBufferStats.indexOfKey(timeUs);
4552d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (index >= 0) {
4553d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
4554d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
4555d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4556d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ALOGI("frame PTS %lld: %lld",
4557d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                timeUs,
4558d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
4559d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4560d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mCodec->mBufferStats.removeItemsAt(index);
4561d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats = NULL;
4562d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
4563d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
4564d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
4566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
4567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
4569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4570054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mDequeuedAt = ++mCodec->mDequeueCounter;
4571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
4572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
4574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4581a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            if (rangeLength == 0 && (!(flags & OMX_BUFFERFLAG_EOS)
4582a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                    || mCodec->mPortEOS[kPortIndexOutput])) {
4583609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                ALOGV("[%s] calling fillBuffer %u",
45845778822d86b0337407514b9372562b86edfa91cdAndreas Huber                     mCodec->mComponentName.c_str(), info->mBufferID);
4585349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
45865778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK_EQ(mCodec->mOMX->fillBuffer(
45875778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mCodec->mNode, info->mBufferID),
45885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         (status_t)OK);
4589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
45905778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
45915778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
45925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
459331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4594577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            sp<AMessage> reply =
45951d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar                new AMessage(kWhatOutputBufferDrained, mCodec);
4596577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
45974bdda35319d5f46efea2089b865c8a64816389cdMarco Nelissen            if (!mCodec->mSentFormat && rangeLength > 0) {
4598577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->sendFormatChange(reply);
45995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
4600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4601308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            if (mCodec->mUseMetadataOnEncoderOutput) {
4602308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                native_handle_t* handle =
4603308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        *(native_handle_t**)(info->mData->data() + 4);
4604308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setPointer("handle", handle);
4605308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeOffset", rangeOffset);
4606308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeLength", rangeLength);
4607308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            } else {
4608308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->setRange(rangeOffset, rangeLength);
4609308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            }
4610496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#if 0
461121ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen            if (mCodec->mNativeWindow == NULL) {
4612496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                if (IsIDR(info->mData)) {
4613496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                    ALOGI("IDR frame");
4614496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                }
46155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
461621ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen#endif
4617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
46188b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            if (mCodec->mSkipCutBuffer != NULL) {
46198b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                mCodec->mSkipCutBuffer->submit(info->mData);
46208b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            }
46215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mData->meta()->setInt64("timeUs", timeUs);
4622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
46235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4624d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatDrainThisBuffer);
4625609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            notify->setInt32("buffer-id", info->mBufferID);
46262d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            notify->setBuffer("buffer", info->mData);
46275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("flags", flags);
4628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4629609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            reply->setInt32("buffer-id", info->mBufferID);
4630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
46315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setMessage("reply", reply);
4632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
46335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->post();
46345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
46355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
4636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (flags & OMX_BUFFERFLAG_EOS) {
46385778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
46395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                sp<AMessage> notify = mCodec->mNotify->dup();
4641d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar                notify->setInt32("what", CodecBase::kWhatEOS);
4642dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                notify->setInt32("err", mCodec->mInputEOSResult);
4643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->post();
4644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexOutput] = true;
4646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
4653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
4655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
4656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4663f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
4664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
4665609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
4666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
4667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
4668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
4669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM);
4670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4671577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    android_native_rect_t crop;
4672577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    if (msg->findRect("crop",
4673577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            &crop.left, &crop.top, &crop.right, &crop.bottom)) {
4674577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar        CHECK_EQ(0, native_window_set_crop(
4675577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->mNativeWindow.get(), &crop));
4676577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    }
4677577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
4678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t render;
4679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mNativeWindow != NULL
46806aade6058521b0dbd35a9a4620f4d04f02f90444Marco Nelissen            && msg->findInt32("render", &render) && render != 0
468179ee2399b67c7a11042c5904dc1309712a76f8cbJianzheng Zhou            && info->mData != NULL && info->mData->size() != 0) {
46826fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        ATRACE_NAME("render");
4683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The client wants this buffer to be rendered.
4684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4685fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        int64_t timestampNs = 0;
4686fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        if (!msg->findInt64("timestampNs", &timestampNs)) {
4687fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // TODO: it seems like we should use the timestamp
4688fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // in the (media)buffer as it potentially came from
4689fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // an input surface, but we did not propagate it prior to
4690fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // API 20.  Perhaps check for target SDK version.
4691fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#if 0
4692fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            if (info->mData->meta()->findInt64("timeUs", &timestampNs)) {
469347aea1f7c58f5302b16822f9e7e1763f2af04ef5Lajos Molnar                ALOGV("using buffer PTS of %" PRId64, timestampNs);
4694fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar                timestampNs *= 1000;
4695fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            }
4696fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#endif
4697fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
4698fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
46995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err;
4700fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        err = native_window_set_buffers_timestamp(mCodec->mNativeWindow.get(), timestampNs);
4701fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        if (err != OK) {
4702fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            ALOGW("failed to set buffer timestamp: %d", err);
4703fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
4704fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
47055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if ((err = mCodec->mNativeWindow->queueBuffer(
4706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNativeWindow.get(),
47071e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                    info->mGraphicBuffer.get(), -1)) == OK) {
4708cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
4709cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        } else {
4710251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
4711cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
4712cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        }
4713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
47146fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        if (mCodec->mNativeWindow != NULL &&
47156fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar            (info->mData == NULL || info->mData->size() != 0)) {
47166fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar            ATRACE_NAME("frame-drop");
47176fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        }
4718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_US;
4719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
4722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
4727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // We cannot resubmit the buffer we just rendered, dequeue
4730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // the spare instead.
4731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info = mCodec->dequeueBufferFromNativeWindow();
4733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (!mCodec->mPortEOS[kPortIndexOutput]) {
4740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // We cannot resubmit the buffer we just rendered, dequeue
4742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // the spare instead.
4743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info = mCodec->dequeueBufferFromNativeWindow();
4745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
4746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4747c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                if (info != NULL) {
4748609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                    ALOGV("[%s] calling fillBuffer %u",
4749c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                         mCodec->mComponentName.c_str(), info->mBufferID);
4750349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4751c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
4752c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                             (status_t)OK);
4753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4754c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4755c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                }
4756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
4763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
4765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
4766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4773f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::UninitializedState::UninitializedState(ACodec *codec)
4774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4775f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4777c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::UninitializedState::stateEntered() {
4778c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("Now uninitialized");
4779ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4780ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (mDeathNotifier != NULL) {
4781f888020c6e2735624f2b2a30e72aca24e17b8b4dMarco Nelissen        IInterface::asBinder(mCodec->mOMX)->unlinkToDeath(mDeathNotifier);
4782ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
4783ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
4784ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4785ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNativeWindow.clear();
4786ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    mCodec->mNode = 0;
4787ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mOMX.clear();
4788ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mQuirks = 0;
4789ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mFlags = 0;
4790308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    mCodec->mUseMetadataOnEncoderOutput = 0;
4791ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mComponentName.clear();
4792c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4793c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4794f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
4795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatSetup:
4799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onSetup(msg);
4801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
48065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case ACodec::kWhatAllocateComponent:
48075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
48085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            onAllocateComponent(msg);
48095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            handled = true;
48105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
48115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
48125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatShutdown:
4814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4815c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
4816c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
4817c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
481854b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            ALOGW_IF(keepComponentAllocated,
481954b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar                     "cannot keep component allocated on shutdown in Uninitialized state");
4820c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4822d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
4823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
4824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4826c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
4827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatFlush:
4830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4832d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
4833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
4834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4836c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
4837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
483930358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        case ACodec::kWhatReleaseCodecInstance:
484030358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        {
484130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            // nothing to do, as we have already signaled shutdown
484230358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            handled = true;
484330358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            break;
484430358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        }
484530358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar
4846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
4848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4850f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4853f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::UninitializedState::onSetup(
4854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4855c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (onAllocateComponent(msg)
4856c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            && mCodec->mLoadedState->onConfigureComponent(msg)) {
4857c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mLoadedState->onStart();
4858c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
48595778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
48605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4861c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
48625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onAllocateComponent");
48635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4864ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    CHECK(mCodec->mNode == 0);
48655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMXClient client;
486748a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung    if (client.connect() != OK) {
486848a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung        mCodec->signalError(OMX_ErrorUndefined, NO_INIT);
486948a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung        return false;
487048a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung    }
4871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<IOMX> omx = client.interface();
4873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
48741d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec);
4875ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4876ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mDeathNotifier = new DeathNotifier(notify);
4877f888020c6e2735624f2b2a30e72aca24e17b8b4dMarco Nelissen    if (IInterface::asBinder(omx)->linkToDeath(mDeathNotifier) != OK) {
4878ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // This was a local binder, if it dies so do we, we won't care
4879ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // about any notifications in the afterlife.
4880ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
4881ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
4882ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4883e671207115fac3914134c61b336d5fa0242c68caAndreas Huber    Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs;
48845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    AString mime;
4886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
48875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString componentName;
4888d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint32_t quirks = 0;
48897791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen    int32_t encoder = false;
48905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findString("componentName", &componentName)) {
4891e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        ssize_t index = matchingCodecs.add();
4892e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        OMXCodec::CodecNameAndQuirks *entry = &matchingCodecs.editItemAt(index);
4893e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        entry->mName = String8(componentName.c_str());
4894afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
4895e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        if (!OMXCodec::findCodecQuirks(
4896e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                    componentName.c_str(), &entry->mQuirks)) {
4897e671207115fac3914134c61b336d5fa0242c68caAndreas Huber            entry->mQuirks = 0;
4898afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
48995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
49005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(msg->findString("mime", &mime));
49015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
49025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("encoder", &encoder)) {
49035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder = false;
49045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
49055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
49065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMXCodec::findMatchingCodecs(
49075778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mime.c_str(),
49085778822d86b0337407514b9372562b86edfa91cdAndreas Huber                encoder, // createEncoder
49095778822d86b0337407514b9372562b86edfa91cdAndreas Huber                NULL,  // matchComponentName
49105778822d86b0337407514b9372562b86edfa91cdAndreas Huber                0,     // flags
4911e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                &matchingCodecs);
49125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
49131065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
49141065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    sp<CodecObserver> observer = new CodecObserver;
4915ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    IOMX::node_id node = 0;
49161065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
49179f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu    status_t err = OMX_ErrorComponentNotFound;
49181065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
49191065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            ++matchIndex) {
4920e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        componentName = matchingCodecs.itemAt(matchIndex).mName.string();
4921e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        quirks = matchingCodecs.itemAt(matchIndex).mQuirks;
4922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4923da153975581fb3161a30452348a5b26ee72d9255Elliott Hughes        pid_t tid = gettid();
4924078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        int prevPriority = androidGetThreadPriority(tid);
4925078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
49269f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu        err = omx->allocateNode(componentName.c_str(), observer, &node);
4927078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, prevPriority);
4928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
49291065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        if (err == OK) {
49301065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            break;
49317a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He        } else {
49327a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He            ALOGW("Allocating component '%s' failed, try next one.", componentName.c_str());
49331065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
49341065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
4935ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        node = 0;
49361065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    }
49371065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
4938ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    if (node == 0) {
49395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!mime.empty()) {
49409f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu            ALOGE("Unable to instantiate a %scoder for type '%s' with err %#x.",
49419f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu                    encoder ? "en" : "de", mime.c_str(), err);
49425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
49439f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu            ALOGE("Unable to instantiate codec '%s' with err %#x.", componentName.c_str(), err);
49445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
4945c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
494652e88b2986536e83a7a6da63461556b8734a85f3Ronghua Wu        mCodec->signalError((OMX_ERRORTYPE)err, makeNoSideEffectStatus(err));
4947c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
4948c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
4949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
49501d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    notify = new AMessage(kWhatOMXMessage, mCodec);
4951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    observer->setNotificationMessage(notify);
4952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mComponentName = componentName;
4954ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    mCodec->mFlags = 0;
4955ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
4956ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (componentName.endsWith(".secure")) {
4957ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        mCodec->mFlags |= kFlagIsSecure;
49581713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        mCodec->mFlags |= kFlagIsGrallocUsageProtected;
49590167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
4960ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
4961ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
4962afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mCodec->mQuirks = quirks;
4963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mOMX = omx;
4964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mNode = node;
4965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
49665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
49675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
4968d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatComponentAllocated);
49695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setString("componentName", mCodec->mComponentName.c_str());
49705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
49715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4972c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4973c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mCodec->changeState(mCodec->mLoadedState);
4974c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4975c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
49765778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
49775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4978c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
4979c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4980c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas HuberACodec::LoadedState::LoadedState(ACodec *codec)
4981c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    : BaseState(codec) {
4982c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4983c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4984c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::stateEntered() {
4985c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
4986c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4987f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mPortEOS[kPortIndexInput] =
4988f6f38287b97ec69b169387add6458f859b770e65Andreas Huber        mCodec->mPortEOS[kPortIndexOutput] = false;
4989f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
4990f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mInputEOSResult = OK;
4991f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
4992054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mDequeueCounter = 0;
4993054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mMetaDataBuffersToSubmit = 0;
4994a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    mCodec->mRepeatFrameDelayUs = -1ll;
4995e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mInputFormat.clear();
4996e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mOutputFormat.clear();
49974e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    mCodec->mBaseOutputFormat.clear();
4998054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4999c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (mCodec->mShutdownInProgress) {
5000c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
5001c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5002c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mShutdownInProgress = false;
5003c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mKeepComponentAllocated = false;
5004c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5005c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        onShutdown(keepComponentAllocated);
5006c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
500754b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    mCodec->mExplicitShutdown = false;
5008f393c33e65ae51a7cf168b4e15771b152f996b32Wei Jia
5009f393c33e65ae51a7cf168b4e15771b152f996b32Wei Jia    mCodec->processDeferredMessages();
5010c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
5011c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5012c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
5013c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (!keepComponentAllocated) {
5014c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK);
5015c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5016c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->changeState(mCodec->mUninitializedState);
5017c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
5018c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
501954b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    if (mCodec->mExplicitShutdown) {
502054b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        sp<AMessage> notify = mCodec->mNotify->dup();
5021d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
502254b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        notify->post();
502354b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        mCodec->mExplicitShutdown = false;
502454b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    }
5025c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
5026c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5027c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
5028c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool handled = false;
5029c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5030c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    switch (msg->what()) {
5031c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatConfigureComponent:
5032c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
5033c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onConfigureComponent(msg);
5034c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
5035c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
5036c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
5037c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
50387cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
50397cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
50407cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            onCreateInputSurface(msg);
50417cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
50427cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
50437cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
50447cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
5045d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        case ACodec::kWhatUsePersistentInputSurface:
5046d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        {
5047d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            onUsePersistentInputSurface(msg);
5048d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            handled = true;
5049d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            break;
5050d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        }
5051d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5052c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatStart:
5053c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
5054c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onStart();
5055c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
5056c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
5057c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
5058c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5059c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatShutdown:
5060c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
5061c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
5062c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
5063c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
5064c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
506554b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
5066c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onShutdown(keepComponentAllocated);
5067c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5068c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
5069c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
5070c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
5071c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5072c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatFlush:
5073c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
5074c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
5075d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
5076c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->post();
5077c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5078c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
5079c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
5080c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
5081c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5082c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        default:
5083c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            return BaseState::onMessageReceived(msg);
5084c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
5085c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5086c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return handled;
5087c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
5088c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5089c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onConfigureComponent(
50905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg) {
50915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onConfigureComponent");
50925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5093ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    CHECK(mCodec->mNode != 0);
50945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
50955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString mime;
50965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findString("mime", &mime));
50975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
50985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mCodec->configureCodec(mime.c_str(), msg);
50995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
51005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
5101c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        ALOGE("[%s] configureCodec returning error %d",
5102c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber              mCodec->mComponentName.c_str(), err);
5103c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber
5104251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5105c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
51065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
51085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
51095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
5110d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatComponentConfigured);
5111e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("input-format", mCodec->mInputFormat);
5112e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("output-format", mCodec->mOutputFormat);
51135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
51145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5115c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5116c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
51175778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
51185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5119d291c222357303b9611cab89d0c3b047584ef377Chong Zhangstatus_t ACodec::LoadedState::setupInputSurface() {
5120d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    status_t err = OK;
5121a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
5122d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mRepeatFrameDelayUs > 0ll) {
5123a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        err = mCodec->mOMX->setInternalOption(
5124a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                mCodec->mNode,
5125a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                kPortIndexInput,
5126a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY,
5127a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                &mCodec->mRepeatFrameDelayUs,
5128a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                sizeof(mCodec->mRepeatFrameDelayUs));
5129a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
5130a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (err != OK) {
5131a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            ALOGE("[%s] Unable to configure option to repeat previous "
5132a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  "frames (err %d)",
5133a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  mCodec->mComponentName.c_str(),
5134a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  err);
5135d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
5136a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
5137a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
5138a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
5139d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mMaxPtsGapUs > 0ll) {
514094ee4b708acfa941581160b267afb79192b1d816Chong Zhang        err = mCodec->mOMX->setInternalOption(
514194ee4b708acfa941581160b267afb79192b1d816Chong Zhang                mCodec->mNode,
514294ee4b708acfa941581160b267afb79192b1d816Chong Zhang                kPortIndexInput,
514394ee4b708acfa941581160b267afb79192b1d816Chong Zhang                IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP,
514494ee4b708acfa941581160b267afb79192b1d816Chong Zhang                &mCodec->mMaxPtsGapUs,
514594ee4b708acfa941581160b267afb79192b1d816Chong Zhang                sizeof(mCodec->mMaxPtsGapUs));
514694ee4b708acfa941581160b267afb79192b1d816Chong Zhang
514794ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (err != OK) {
514894ee4b708acfa941581160b267afb79192b1d816Chong Zhang            ALOGE("[%s] Unable to configure max timestamp gap (err %d)",
514972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    mCodec->mComponentName.c_str(),
515072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    err);
5151d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
51522c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
51532c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
51542c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
5155d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mMaxFps > 0) {
515637b2b389139ed638831e49708c947863eef631efRonghua Wu        err = mCodec->mOMX->setInternalOption(
515737b2b389139ed638831e49708c947863eef631efRonghua Wu                mCodec->mNode,
515837b2b389139ed638831e49708c947863eef631efRonghua Wu                kPortIndexInput,
515937b2b389139ed638831e49708c947863eef631efRonghua Wu                IOMX::INTERNAL_OPTION_MAX_FPS,
516037b2b389139ed638831e49708c947863eef631efRonghua Wu                &mCodec->mMaxFps,
516137b2b389139ed638831e49708c947863eef631efRonghua Wu                sizeof(mCodec->mMaxFps));
516237b2b389139ed638831e49708c947863eef631efRonghua Wu
516337b2b389139ed638831e49708c947863eef631efRonghua Wu        if (err != OK) {
516437b2b389139ed638831e49708c947863eef631efRonghua Wu            ALOGE("[%s] Unable to configure max fps (err %d)",
516537b2b389139ed638831e49708c947863eef631efRonghua Wu                    mCodec->mComponentName.c_str(),
516637b2b389139ed638831e49708c947863eef631efRonghua Wu                    err);
5167d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
516837b2b389139ed638831e49708c947863eef631efRonghua Wu        }
516937b2b389139ed638831e49708c947863eef631efRonghua Wu    }
517037b2b389139ed638831e49708c947863eef631efRonghua Wu
5171d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mTimePerCaptureUs > 0ll
51722c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            && mCodec->mTimePerFrameUs > 0ll) {
51732c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        int64_t timeLapse[2];
51742c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[0] = mCodec->mTimePerFrameUs;
51752c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[1] = mCodec->mTimePerCaptureUs;
51762c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        err = mCodec->mOMX->setInternalOption(
51772c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                mCodec->mNode,
51782c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                kPortIndexInput,
51792c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                IOMX::INTERNAL_OPTION_TIME_LAPSE,
51802c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                &timeLapse[0],
51812c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                sizeof(timeLapse));
51822c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
51832c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (err != OK) {
51842c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            ALOGE("[%s] Unable to configure time lapse (err %d)",
51852c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    mCodec->mComponentName.c_str(),
51862c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    err);
5187d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
51882c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
51892c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
519072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
5191d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mCreateInputBuffersSuspended) {
519272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        bool suspend = true;
519372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        err = mCodec->mOMX->setInternalOption(
519472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                mCodec->mNode,
519572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                kPortIndexInput,
519672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                IOMX::INTERNAL_OPTION_SUSPEND,
519772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                &suspend,
519872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                sizeof(suspend));
519972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
520072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
520172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("[%s] Unable to configure option to suspend (err %d)",
520294ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  mCodec->mComponentName.c_str(),
520394ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  err);
5204d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
520594ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
520694ee4b708acfa941581160b267afb79192b1d816Chong Zhang    }
520794ee4b708acfa941581160b267afb79192b1d816Chong Zhang
5208d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    return OK;
5209d291c222357303b9611cab89d0c3b047584ef377Chong Zhang}
5210d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5211d291c222357303b9611cab89d0c3b047584ef377Chong Zhangvoid ACodec::LoadedState::onCreateInputSurface(
5212d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        const sp<AMessage> & /* msg */) {
5213d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    ALOGV("onCreateInputSurface");
5214d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5215d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<AMessage> notify = mCodec->mNotify->dup();
5216d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    notify->setInt32("what", CodecBase::kWhatInputSurfaceCreated);
5217d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5218d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<IGraphicBufferProducer> bufferProducer;
5219d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    status_t err = mCodec->mOMX->createInputSurface(
5220d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            mCodec->mNode, kPortIndexInput, &bufferProducer);
5221d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5222d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (err == OK) {
5223d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        err = setupInputSurface();
5224d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    }
5225d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
52267cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err == OK) {
52277cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setObject("input-surface",
52287cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                new BufferProducerWrapper(bufferProducer));
52297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else {
52307cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // Can't use mCodec->signalError() here -- MediaCodec won't forward
52317cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // the error through because it's in the "configured" state.  We
52327cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // send a kWhatInputSurfaceCreated with an error value instead.
52337cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGE("[%s] onCreateInputSurface returning error %d",
52347cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                mCodec->mComponentName.c_str(), err);
52357cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setInt32("err", err);
52367cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
52377cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->post();
52387cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
52397cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
5240d291c222357303b9611cab89d0c3b047584ef377Chong Zhangvoid ACodec::LoadedState::onUsePersistentInputSurface(
5241d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        const sp<AMessage> &msg) {
5242d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    ALOGV("onUsePersistentInputSurface");
5243d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5244d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<AMessage> notify = mCodec->mNotify->dup();
5245d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    notify->setInt32("what", CodecBase::kWhatInputSurfaceAccepted);
5246d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5247d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<RefBase> obj;
5248d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    CHECK(msg->findObject("input-surface", &obj));
5249d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<PersistentSurface> surface = static_cast<PersistentSurface *>(obj.get());
5250d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5251d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    status_t err = mCodec->mOMX->usePersistentInputSurface(
5252d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            mCodec->mNode, kPortIndexInput, surface->getBufferConsumer());
5253d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5254d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (err == OK) {
5255d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        err = setupInputSurface();
5256d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    }
5257d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5258d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (err != OK) {
5259d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        // Can't use mCodec->signalError() here -- MediaCodec won't forward
5260d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        // the error through because it's in the "configured" state.  We
5261d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        // send a kWhatInputSurfaceAccepted with an error value instead.
5262d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        ALOGE("[%s] onUsePersistentInputSurface returning error %d",
5263d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                mCodec->mComponentName.c_str(), err);
5264d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        notify->setInt32("err", err);
5265d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    }
5266d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    notify->post();
5267d291c222357303b9611cab89d0c3b047584ef377Chong Zhang}
5268d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5269c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onStart() {
52705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onStart");
52715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
52725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ(mCodec->mOMX->sendCommand(
52735778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
5274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
5275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->changeState(mCodec->mLoadedToIdleState);
5277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5281f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
5282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5285f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::LoadedToIdleState::stateEntered() {
52863856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
5287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5288cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    status_t err;
5289cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    if ((err = allocateBuffers()) != OK) {
529029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to allocate buffers after transitioning to IDLE state "
5291cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             "(error 0x%08x)",
5292cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             err);
5293cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
5294251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
529591bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber
529691bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber        mCodec->changeState(mCodec->mLoadedState);
5297cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    }
5298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5300f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::LoadedToIdleState::allocateBuffers() {
5301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
5302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
5304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
5305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mCodec->allocateBuffersOnPort(kPortIndexOutput);
5308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5310f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
5311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
531272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
5313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
5316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
53196507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
53206507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
53216507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
53226507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
53236507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
53246507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
53256463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatResume:
53266463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
53276463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We'll be active soon enough.
53286463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
53296463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
53306463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
53316463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatFlush:
53326463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
53336463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We haven't even started yet, so we're flushed alright...
53346463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            sp<AMessage> notify = mCodec->mNotify->dup();
5335d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
53366463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->post();
53376463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
53386463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
53396463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
5340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
5342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5345f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onOMXEvent(
5346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
5351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
5352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
5354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting),
5355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
5356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mIdleToExecutingState);
5358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5369f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
5370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5373f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToExecutingState::stateEntered() {
53743856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
5375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5377f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
5378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
537972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
5380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
5383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5386d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatResume:
5387d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
5388d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We'll be active soon enough.
5389d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
5390d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
5391d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
5392d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatFlush:
5393d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
5394d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We haven't even started yet, so we're flushed alright...
5395d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
5396d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
5397d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->post();
5398d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
5399d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
5400d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
5401d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
54026507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
54036507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
54046507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
54056507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
54066507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
54076507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
5408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
5410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5413f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onOMXEvent(
5414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
5419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateExecuting);
5420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mExecutingState->resume();
5422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingState);
5423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5434f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingState::ExecutingState(ACodec *codec)
5435349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    : BaseState(codec),
5436349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber      mActive(false) {
5437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5439f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
5440ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
5441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
5442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5444054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputMetaBuffers() {
5445054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // submit as many buffers as there are input buffers with the codec
5446054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // in case we are in port reconfiguring
5447054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
5448054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
5449054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5450054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) {
5451054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            if (mCodec->submitOutputMetaDataBuffer() != OK)
5452054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                break;
5453054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
5454054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
54554dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
54564dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
54574dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
5458054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
5459054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5460054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitRegularOutputBuffers() {
5461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
5462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
5463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mCodec->mNativeWindow != NULL) {
5465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(info->mStatus == BufferInfo::OWNED_BY_US
5466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
5467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
5469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                continue;
5470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
5472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
5473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5475ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        ALOGV("[%s] calling fillBuffer %u",
5476349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str(), info->mBufferID);
5477349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
5479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
5480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
5482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5485054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputBuffers() {
5486c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar    submitRegularOutputBuffers();
5487054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mCodec->mStoreMetaDataInOutputBuffers) {
5488054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        submitOutputMetaBuffers();
5489054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
5490054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
5491054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5492f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::resume() {
5493349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    if (mActive) {
54943856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] We're already active, no need to resume.",
5495349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str());
5496349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5497349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        return;
5498349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    }
5499349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    submitOutputBuffers();
5501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
55023cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    // Post all available input buffers
5503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_GT(mCodec->mBuffers[kPortIndexInput].size(), 0u);
55043cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); i++) {
55053cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
55063cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_US) {
55073cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar            postFillThisBuffer(info);
55083cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        }
55093cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    }
5510349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5511349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    mActive = true;
5512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5514f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::stateEntered() {
55153856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
5516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->processDeferredMessages();
5518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5520f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
5521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5526c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
5527c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
5528c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
5529c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5530c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mShutdownInProgress = true;
553154b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
5532c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mKeepComponentAllocated = keepComponentAllocated;
5533c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5534349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
5535349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
5537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
5538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
5539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingToIdleState);
5541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
55487a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong            ALOGV("[%s] ExecutingState flushing now "
5549ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                 "(codec owns %zu/%zu input, %zu/%zu output).",
5550d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mComponentName.c_str(),
5551d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
5552d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexInput].size(),
5553d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
5554d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexOutput].size());
5555d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
5556349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
5557349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
5559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandFlush, OMX_ALL),
5560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
5561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mFlushingState);
5563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatResume:
5568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            resume();
5570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5575496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
5576496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
5577496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            status_t err = mCodec->requestIDRFrame();
5578496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            if (err != OK) {
5579496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                ALOGW("Requesting an IDR frame failed.");
5580496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            }
5581496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5582496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            handled = true;
5583496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
5584496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
5585496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5586a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
5587a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
5588a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
5589a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
5590a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5591a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = mCodec->setParameters(params);
5592a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5593a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> reply;
5594a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            if (msg->findMessage("reply", &reply)) {
5595a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->setInt32("err", err);
5596a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->post();
5597a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            }
5598a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5599a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            handled = true;
5600a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
5601a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
5602a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
56037cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
56047cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
56056507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
56067cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
56077cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
56087cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
56097cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
56104dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
56114dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        case kWhatSubmitOutputMetaDataBufferIfEOS:
56124dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        {
56134dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            if (mCodec->mPortEOS[kPortIndexInput] &&
56144dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    !mCodec->mPortEOS[kPortIndexOutput]) {
56154dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                status_t err = mCodec->submitOutputMetaDataBuffer();
56164dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                if (err == OK) {
56174dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
56184dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                }
56194dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            }
56204dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            return true;
56214dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        }
56224dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
5623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5631a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t ACodec::setParameters(const sp<AMessage> &params) {
5632a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    int32_t videoBitrate;
5633530fdbdc1b5491f3fbf172752834d1515701e142Lajos Molnar    if (params->findInt32("video-bitrate", &videoBitrate)) {
5634a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        OMX_VIDEO_CONFIG_BITRATETYPE configParams;
5635a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        InitOMXParams(&configParams);
5636a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nPortIndex = kPortIndexOutput;
5637a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nEncodeBitrate = videoBitrate;
5638a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5639a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        status_t err = mOMX->setConfig(
5640a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                mNode,
5641a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                OMX_IndexConfigVideoBitrate,
5642a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                &configParams,
5643a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                sizeof(configParams));
5644a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5645a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        if (err != OK) {
5646a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
5647a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                   videoBitrate, err);
5648a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5649a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            return err;
5650a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
5651a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    }
5652a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
565372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    int64_t skipFramesBeforeUs;
565472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (params->findInt64("skip-frames-before", &skipFramesBeforeUs)) {
565572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        status_t err =
565672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mOMX->setInternalOption(
565772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     mNode,
565872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     kPortIndexInput,
565972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     IOMX::INTERNAL_OPTION_START_TIME,
566072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     &skipFramesBeforeUs,
566172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     sizeof(skipFramesBeforeUs));
566272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
566372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
566472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("Failed to set parameter 'skip-frames-before' (err %d)", err);
566572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            return err;
566672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
566772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
566872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
5669e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    int32_t dropInputFrames;
5670e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    if (params->findInt32("drop-input-frames", &dropInputFrames)) {
5671e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        bool suspend = dropInputFrames != 0;
5672e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
5673b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err =
5674b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            mOMX->setInternalOption(
5675e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     mNode,
5676e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     kPortIndexInput,
5677e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     IOMX::INTERNAL_OPTION_SUSPEND,
5678e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     &suspend,
5679b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber                     sizeof(suspend));
5680b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
5681b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
5682b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err);
5683b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
5684b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
5685b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    }
5686b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
5687b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    int32_t dummy;
5688b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    if (params->findInt32("request-sync", &dummy)) {
5689b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err = requestIDRFrame();
5690b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
5691b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
5692b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Requesting a sync frame failed w/ err %d", err);
5693b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
5694b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
5695e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    }
5696e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
56978db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    float rate;
56988db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    if (params->findFloat("operating-rate", &rate) && rate > 0) {
56998db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        status_t err = setOperatingRate(rate, mIsVideo);
57008db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        if (err != OK) {
57018db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu            ALOGE("Failed to set parameter 'operating-rate' (err %d)", err);
57028db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu            return err;
57038db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        }
57048db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    }
57058db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu
5706a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return OK;
5707a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
5708a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
57096507d14c6d10f93d390de62b9eed267f9b544985Andy McFaddenvoid ACodec::onSignalEndOfInputStream() {
57106507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    sp<AMessage> notify = mNotify->dup();
5711d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatSignaledInputEOS);
57126507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
57136507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    status_t err = mOMX->signalEndOfInputStream(mNode);
57146507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    if (err != OK) {
57156507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        notify->setInt32("err", err);
57166507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    }
57176507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->post();
57186507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden}
57196507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
5720f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onOMXEvent(
5721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventPortSettingsChanged:
5724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
5726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
572731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
5728054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mCodec->mMetaDataBuffersToSubmit = 0;
5729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
5730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
5731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_CommandPortDisable, kPortIndexOutput),
5732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
5733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5734349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                mCodec->freeOutputBuffersNotOwnedByComponent();
5735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
573731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            } else if (data2 == OMX_IndexConfigCommonOutputCrop) {
573831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
5739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
5740ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08x",
5741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->mComponentName.c_str(), data2);
5742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventBufferFlag:
5748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5759f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
5760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ACodec *codec)
5761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5764f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
5765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
5766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput) {
5767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return FREE_BUFFERS;
5768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
5771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
5773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5775f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onMessageReceived(
5776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
5777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5782349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case kWhatResume:
5783e6eea3a6b6e0cf92287ec1ceb8350f201d17e1acPer Persson        case kWhatSetParameters:
5784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5785349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            if (msg->what() == kWhatResume) {
57863856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
5787349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            }
5788349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
5790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5802f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::OutputPortSettingsChangedState::stateEntered() {
58033856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now handling output port settings change",
5804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mCodec->mComponentName.c_str());
5805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5807f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onOMXEvent(
5808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
5813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
5814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
58153856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now disabled.",
5816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
5817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mCodec->mBuffers[kPortIndexOutput].isEmpty());
5819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mDealer[kPortIndexOutput].clear();
5820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
5822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput),
5823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
5824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5825cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                status_t err;
5826cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                if ((err = mCodec->allocateBuffersOnPort(
5827cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                                kPortIndexOutput)) != OK) {
582829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("Failed to allocate output port buffers after "
5829cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         "port reconfiguration (error 0x%08x)",
5830cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         err);
5831cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
5832251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5833d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
5834755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // This is technically not correct, but appears to be
5835755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the only way to free the component instance.
5836755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // Controlled transitioning from excecuting->idle
5837755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // and idle->loaded seem impossible probably because
5838755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the output port never finishes re-enabling.
5839755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mShutdownInProgress = true;
5840755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mKeepComponentAllocated = false;
5841755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->changeState(mCodec->mLoadedState);
5842cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                }
5843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
5845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
5846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
5847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
584831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
584931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
58503856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now reenabled.",
5851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
5852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5853349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                if (mCodec->mExecutingState->active()) {
5854349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    mCodec->mExecutingState->submitOutputBuffers();
5855349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                }
5856349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mExecutingState);
5858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
5860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
5863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
5867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5872f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
58735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : BaseState(codec),
58745778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mComponentNowIdle(false) {
5875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5877f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
5878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
5884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
5885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
5886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
5892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5905f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::stateEntered() {
59063856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
590731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
59085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mComponentNowIdle = false;
590931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mCodec->mSentFormat = false;
5910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5912f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onOMXEvent(
5913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
5918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
5919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
59205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mComponentNowIdle = true;
59215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            changeStateIfWeOwnAllBuffers();
5923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5927349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
5928349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventBufferFlag:
5929349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
5930349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We're shutting down and don't care about this anymore.
5931349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
5932349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
5933349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
59380af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
5939f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
59405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
5941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->sendCommand(
5942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded),
5943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
5944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexInput), (status_t)OK);
5946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexOutput), (status_t)OK);
5947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
59480167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown)
59490167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && mCodec->mNativeWindow != NULL) {
5950bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // We push enough 1x1 blank buffers to ensure that one of
5951bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // them has made it to the display.  This allows the OMX
5952bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // component teardown to zero out any protected buffers
5953bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // without the risk of scanning out one of those buffers.
5954b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar            pushBlankBuffersToNativeWindow(mCodec->mNativeWindow.get());
5955bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
5956bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
5957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mIdleToLoadedState);
5958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5961f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onInputBufferFilled(
5962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
5963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
5964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
5966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5968f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onOutputBufferDrained(
5969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
5970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
5971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
5973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5977f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
5978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5981f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
5982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
5988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
5996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
5997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
5998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
6003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
6007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6009f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToLoadedState::stateEntered() {
60103856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
6011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6013f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onOMXEvent(
6014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
6016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
6017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
6019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateLoaded);
6020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6021c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->changeState(mCodec->mLoadedState);
6022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
6028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
6032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6033f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::FlushingState::FlushingState(ACodec *codec)
6034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
6035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6037f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::stateEntered() {
60383856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
6039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
6041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6043f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
6044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
6045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
6047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
6048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
6050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
6054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing this right now.
6056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
6062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
6066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6068f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onOMXEvent(
6069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6070ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGV("[%s] FlushingState onOMXEvent(%u,%d)",
6071ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar            mCodec->mComponentName.c_str(), event, (OMX_S32)data1);
6072d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
6073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
6074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
6075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandFlush);
6077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
6079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(!mFlushComplete[data2]);
6080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mFlushComplete[data2] = true;
6081e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber
6082e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                if (mFlushComplete[kPortIndexInput]
6083e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                        && mFlushComplete[kPortIndexOutput]) {
6084e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                    changeStateIfWeOwnAllBuffers();
6085e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                }
6086f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
6087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, OMX_ALL);
6088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexInput]);
6089f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexOutput]);
6090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                changeStateIfWeOwnAllBuffers();
6092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
6093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6094f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6095f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6097349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
6098349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
60991d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec);
6100349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("type", omx_message::EVENT);
6101609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            msg->setInt32("node", mCodec->mNode);
6102349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("event", event);
6103349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data1", data1);
6104349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data2", data2);
6105349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
61063856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
6107349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                 mCodec->mComponentName.c_str());
6108349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6109349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mCodec->deferMessage(msg);
6110349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6111349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
6112349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
6113349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
6116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
6119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6121f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
6122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
6123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
6125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6127f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
6128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
6129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
6131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6133f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
6134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mFlushComplete[kPortIndexInput]
6135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mFlushComplete[kPortIndexOutput]
6136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mCodec->allYourBuffersAreBelongToUs()) {
61377e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // We now own all buffers except possibly those still queued with
61387e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // the native window for rendering. Let's get those back as well.
61397e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
61407e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
6141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
6142d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatFlushCompleted);
6143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->post();
6144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->mPortEOS[kPortIndexInput] =
6146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mPortEOS[kPortIndexOutput] = false;
6147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6148dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber        mCodec->mInputEOSResult = OK;
6149dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
6150f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        if (mCodec->mSkipCutBuffer != NULL) {
6151f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen            mCodec->mSkipCutBuffer->clear();
6152f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        }
6153f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen
6154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mExecutingState);
6155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
6159