ACodec.cpp revision d291c222357303b9611cab89d0c3b047584ef377
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>
453a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber#include <media/hardware/HardwareAPI.h>
463a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
4797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu#include <OMX_AudioExt.h>
484154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev#include <OMX_VideoExt.h>
49f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <OMX_Component.h>
5097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu#include <OMX_IndexExt.h>
51f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
52496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#include "include/avc_utils.h"
53496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
54f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android {
55f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
56251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// OMX errors are directly mapped into status_t range if
57251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// there is no corresponding MediaError status code.
58251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Use the statusFromOMXError(int32_t omxError) function.
59251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung//
60251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Currently this is a direct map.
61251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// See frameworks/native/include/media/openmax/OMX_Core.h
62251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung//
63251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Vendor OMX errors     from 0x90000000 - 0x9000FFFF
64251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Extension OMX errors  from 0x8F000000 - 0x90000000
65251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Standard OMX errors   from 0x80001000 - 0x80001024 (0x80001024 current)
66251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung//
67251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
68251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// returns true if err is a recognized OMX error code.
69251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// as OMX error is OMX_S32, this is an int32_t type
70251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hungstatic inline bool isOMXError(int32_t err) {
71251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    return (ERROR_CODEC_MIN <= err && err <= ERROR_CODEC_MAX);
72251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung}
73251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
74251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// converts an OMX error to a status_t
75251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hungstatic inline status_t statusFromOMXError(int32_t omxError) {
76251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    switch (omxError) {
77251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case OMX_ErrorInvalidComponentName:
78251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case OMX_ErrorComponentNotFound:
79251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return NAME_NOT_FOUND; // can trigger illegal argument error for provided names.
80251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    default:
81251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return isOMXError(omxError) ? omxError : 0; // no translation required
82251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
83251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung}
84251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
85251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// checks and converts status_t to a non-side-effect status_t
86251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hungstatic inline status_t makeNoSideEffectStatus(status_t err) {
87251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    switch (err) {
88251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // the following errors have side effects and may come
89251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // from other code modules. Remap for safety reasons.
90251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case INVALID_OPERATION:
91251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case DEAD_OBJECT:
92251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return UNKNOWN_ERROR;
93251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    default:
94251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return err;
95251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
96251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung}
97251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
98f933441648ef6a71dee783d733aac17b9508b452Andreas Hubertemplate<class T>
99f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic void InitOMXParams(T *params) {
100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nSize = sizeof(T);
101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nVersionMajor = 1;
102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nVersionMinor = 0;
103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nRevision = 0;
104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nStep = 0;
105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
107f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct CodecObserver : public BnOMXObserver {
108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CodecObserver() {}
109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void setNotificationMessage(const sp<AMessage> &msg) {
111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mNotify = msg;
112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // from IOMXObserver
115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onMessage(const omx_message &omx_msg) {
116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> msg = mNotify->dup();
117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->setInt32("type", omx_msg.type);
119609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        msg->setInt32("node", omx_msg.node);
120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        switch (omx_msg.type) {
122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::EVENT:
123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("event", omx_msg.u.event_data.event);
125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("data1", omx_msg.u.event_data.data1);
126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("data2", omx_msg.u.event_data.data2);
127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::EMPTY_BUFFER_DONE:
131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
132609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                msg->setInt32("buffer", omx_msg.u.buffer_data.buffer);
133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::FILL_BUFFER_DONE:
137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
138609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                msg->setInt32(
139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "buffer", omx_msg.u.extended_buffer_data.buffer);
140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "range_offset",
142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.range_offset);
143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "range_length",
145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.range_length);
146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "flags",
148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.flags);
149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt64(
150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "timestamp",
151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.timestamp);
152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            default:
156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                TRESPASS();
157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->post();
161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
163f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual ~CodecObserver() {}
165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
166f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> mNotify;
168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(CodecObserver);
170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
174f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::BaseState : public AState {
175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState(ACodec *codec, const sp<AState> &parentState = NULL);
176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
177f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    enum PortMode {
179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        KEEP_BUFFERS,
180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        RESUBMIT_BUFFERS,
181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        FREE_BUFFERS,
182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ACodec *mCodec;
185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void postFillThisBuffer(BufferInfo *info);
196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
197f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXMessage(const sp<AMessage> &msg);
199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXEmptyBufferDone(IOMX::buffer_id bufferID);
201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXFillBufferDone(
203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID,
204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            size_t rangeOffset, size_t rangeLength,
205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            OMX_U32 flags,
206784e24e386b088c05d653ab482f2e95cb53e3d01Andy Hung            int64_t timeUs);
207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void getMoreInputDataIfPossible();
209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(BaseState);
211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
215ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberstruct ACodec::DeathNotifier : public IBinder::DeathRecipient {
216ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    DeathNotifier(const sp<AMessage> &notify)
217ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        : mNotify(notify) {
218ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
219ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
220ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual void binderDied(const wp<IBinder> &) {
221ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mNotify->post();
222ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
223ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
224ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprotected:
225ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual ~DeathNotifier() {}
226ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
227ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprivate:
228ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> mNotify;
229ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
230ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(DeathNotifier);
231ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber};
232ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
233f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::UninitializedState : public ACodec::BaseState {
234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    UninitializedState(ACodec *codec);
235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
236f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
238c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
240f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void onSetup(const sp<AMessage> &msg);
242c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onAllocateComponent(const sp<AMessage> &msg);
243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
244ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<DeathNotifier> mDeathNotifier;
245ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(UninitializedState);
247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
251c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberstruct ACodec::LoadedState : public ACodec::BaseState {
252c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    LoadedState(ACodec *codec);
253c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
254c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprotected:
255c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
256c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
257c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
258c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprivate:
259c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    friend struct ACodec::UninitializedState;
260c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
261c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onConfigureComponent(const sp<AMessage> &msg);
2627cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    void onCreateInputSurface(const sp<AMessage> &msg);
263d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    void onUsePersistentInputSurface(const sp<AMessage> &msg);
264c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onStart();
265c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onShutdown(bool keepComponentAllocated);
266c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
267d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    status_t setupInputSurface();
268d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
269c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedState);
270c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber};
271c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
272c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
273c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
274f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::LoadedToIdleState : public ACodec::BaseState {
275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    LoadedToIdleState(ACodec *codec);
276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
277f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
282f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t allocateBuffers();
284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedToIdleState);
286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
290f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToExecutingState : public ACodec::BaseState {
291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToExecutingState(ACodec *codec);
292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
293f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
298f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToExecutingState);
300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
304f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingState : public ACodec::BaseState {
305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingState(ACodec *codec);
306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
307054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitRegularOutputBuffers();
308054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitOutputMetaBuffers();
309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void submitOutputBuffers();
310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Submit output buffers to the decoder, submit input buffers to client
312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // to fill with data.
313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void resume();
314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
315349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    // Returns true iff input and output buffers are in play.
316349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool active() const { return mActive; }
317349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
318f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
325f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
326349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool mActive;
327349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingState);
329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
333f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::OutputPortSettingsChangedState : public ACodec::BaseState {
334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OutputPortSettingsChangedState(ACodec *codec);
335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
336f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
343f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(OutputPortSettingsChangedState);
345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
349f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingToIdleState : public ACodec::BaseState {
350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingToIdleState(ACodec *codec);
351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
352f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
361f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool mComponentNowIdle;
3655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingToIdleState);
367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
371f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToLoadedState : public ACodec::BaseState {
372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToLoadedState(ACodec *codec);
373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
374f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
380f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToLoadedState);
382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
386f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::FlushingState : public ACodec::BaseState {
387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    FlushingState(ACodec *codec);
388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
389f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
398f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool mFlushComplete[2];
400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(FlushingState);
404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
408f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ACodec()
409afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    : mQuirks(0),
410609b815a3131d22da38b2f452faa9f89daad4039Andy Hung      mNode(0),
4115778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mSentFormat(false),
4128db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu      mIsVideo(false),
413c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber      mIsEncoder(false),
414308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang      mUseMetadataOnEncoderOutput(false),
4159806555d3930be43e11106281dee354820ac1c88Andreas Huber      mShutdownInProgress(false),
41654b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar      mExplicitShutdown(false),
4179806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderDelay(0),
4189806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderPadding(0),
419e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang      mRotationDegrees(0),
4209806555d3930be43e11106281dee354820ac1c88Andreas Huber      mChannelMaskPresent(false),
421054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mChannelMask(0),
422054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mDequeueCounter(0),
423054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mStoreMetaDataInOutputBuffers(false),
424a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber      mMetaDataBuffersToSubmit(0),
42594ee4b708acfa941581160b267afb79192b1d816Chong Zhang      mRepeatFrameDelayUs(-1ll),
4262c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang      mMaxPtsGapUs(-1ll),
42737b2b389139ed638831e49708c947863eef631efRonghua Wu      mMaxFps(-1),
4282c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang      mTimePerFrameUs(-1ll),
429609b815a3131d22da38b2f452faa9f89daad4039Andy Hung      mTimePerCaptureUs(-1ll),
430ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad      mCreateInputBuffersSuspended(false),
431ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad      mTunneled(false) {
432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mUninitializedState = new UninitializedState(this);
433c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mLoadedState = new LoadedState(this);
434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mLoadedToIdleState = new LoadedToIdleState(this);
435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToExecutingState = new IdleToExecutingState(this);
436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingState = new ExecutingState(this);
437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOutputPortSettingsChangedState =
439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        new OutputPortSettingsChangedState(this);
440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingToIdleState = new ExecutingToIdleState(this);
442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToLoadedState = new IdleToLoadedState(this);
443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushingState = new FlushingState(this);
444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
446dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber    mInputEOSResult = OK;
447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeState(mUninitializedState);
449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
451f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::~ACodec() {
452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
454f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::setNotificationMessage(const sp<AMessage> &msg) {
455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mNotify = msg;
456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
458f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::initiateSetup(const sp<AMessage> &msg) {
459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setWhat(kWhatSetup);
4601d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    msg->setTarget(this);
461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
464a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Hubervoid ACodec::signalSetParameters(const sp<AMessage> &params) {
4651d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetParameters, this);
466a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->setMessage("params", params);
467a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->post();
468a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
469a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4705778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateAllocateComponent(const sp<AMessage> &msg) {
4715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatAllocateComponent);
4721d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    msg->setTarget(this);
4735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4745778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4765778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateConfigureComponent(const sp<AMessage> &msg) {
4775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatConfigureComponent);
4781d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    msg->setTarget(this);
4795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4805778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4827cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::initiateCreateInputSurface() {
4831d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatCreateInputSurface, this))->post();
4847cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
4857cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
486d291c222357303b9611cab89d0c3b047584ef377Chong Zhangvoid ACodec::initiateUsePersistentInputSurface(
487d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        const sp<PersistentSurface> &surface) {
488d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<AMessage> msg = new AMessage(kWhatUsePersistentInputSurface, this);
489d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    msg->setObject("input-surface", surface);
490d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    msg->post();
491d291c222357303b9611cab89d0c3b047584ef377Chong Zhang}
492d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
4937cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::signalEndOfInputStream() {
4941d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatSignalEndOfInputStream, this))->post();
4957cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
4967cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4975778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateStart() {
4981d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatStart, this))->post();
4995778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
5005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
501f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalFlush() {
5027a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] signalFlush", mComponentName.c_str());
5031d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatFlush, this))->post();
504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
506f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalResume() {
5071d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatResume, this))->post();
508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
510c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::initiateShutdown(bool keepComponentAllocated) {
5111d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatShutdown, this);
512c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->setInt32("keepComponentAllocated", keepComponentAllocated);
513c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->post();
51430358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar    if (!keepComponentAllocated) {
51530358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        // ensure shutdown completes in 3 seconds
5161d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar        (new AMessage(kWhatReleaseCodecInstance, this))->post(3000000);
51730358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar    }
518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
520496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubervoid ACodec::signalRequestIDRFrame() {
5211d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatRequestIDRFrame, this))->post();
522496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
523496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5244dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
5254dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// Some codecs may return input buffers before having them processed.
5264dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// This causes a halt if we already signaled an EOS on the input
5274dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// port.  For now keep submitting an output buffer if there was an
5284dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// EOS on the input port, but not yet on the output port.
5294dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnarvoid ACodec::signalSubmitOutputMetaDataBufferIfEOS_workaround() {
5304dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    if (mPortEOS[kPortIndexInput] && !mPortEOS[kPortIndexOutput] &&
5314dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            mMetaDataBuffersToSubmit > 0) {
5321d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar        (new AMessage(kWhatSubmitOutputMetaDataBufferIfEOS, this))->post();
5334dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    }
5344dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar}
5354dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
536f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mDealer[portIndex] == NULL);
540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mBuffers[portIndex].isEmpty());
541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
544054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (mStoreMetaDataInOutputBuffers) {
545054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputMetaDataBuffers();
546054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
547054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputBuffersFromNativeWindow();
548054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
5495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
5505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
5515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
5525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = portIndex;
553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
5555778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err == OK) {
558609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGV("[%s] Allocating %u buffers of size %u on %s port",
5595778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mComponentName.c_str(),
5605778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    def.nBufferCountActual, def.nBufferSize,
5615778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    portIndex == kPortIndexInput ? "input" : "output");
562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            size_t totalSize = def.nBufferCountActual * def.nBufferSize;
5645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
5675778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
5685778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(mem.get() != NULL);
569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
570ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                BufferInfo info;
571ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                info.mStatus = BufferInfo::OWNED_BY_US;
572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
573afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                uint32_t requiresAllocateBufferBit =
574afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                    (portIndex == kPortIndexInput)
575afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        ? OMXCodec::kRequiresAllocateBufferOnInputPorts
576afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        : OMXCodec::kRequiresAllocateBufferOnOutputPorts;
5771065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
578308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                if ((portIndex == kPortIndexInput && (mFlags & kFlagIsSecure))
579308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        || mUseMetadataOnEncoderOutput) {
580ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    mem.clear();
581ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
582ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    void *ptr;
583ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->allocateBuffer(
584ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, def.nBufferSize, &info.mBufferID,
585ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            &ptr);
586ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
587308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    int32_t bufSize = mUseMetadataOnEncoderOutput ?
588308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                            (4 + sizeof(buffer_handle_t)) : def.nBufferSize;
589308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
590308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    info.mData = new ABuffer(ptr, bufSize);
591ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                } else if (mQuirks & requiresAllocateBufferBit) {
5925778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    err = mOMX->allocateBufferWithBackup(
593ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, mem, &info.mBufferID);
5945778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
595ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->useBuffer(mNode, portIndex, mem, &info.mBufferID);
596ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                }
597ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
598ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                if (mem != NULL) {
599ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    info.mData = new ABuffer(mem->pointer(), def.nBufferSize);
6005778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
6011065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
6025778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mBuffers[portIndex].push(info);
6031065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            }
6041065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
6055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
6085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
6095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> notify = mNotify->dup();
612d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatBuffersAllocated);
6135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("portIndex", portIndex);
615eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
616eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    sp<PortDescription> desc = new PortDescription;
617eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
6185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
619eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        const BufferInfo &info = mBuffers[portIndex][i];
6205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
621eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        desc->addBuffer(info.mBufferID, info.mData);
622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
624eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    notify->setObject("portDesc", desc);
6255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->post();
6265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
630054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::configureOutputBuffersFromNativeWindow(
631054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 *bufferCount, OMX_U32 *bufferSize,
632054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 *minUndequeuedBuffers) {
633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = kPortIndexOutput;
636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
644ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    err = native_window_set_buffers_dimensions(
645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameWidth,
647ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar            def.format.video.nFrameHeight);
648ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar
649ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    if (err != 0) {
650ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        ALOGE("native_window_set_buffers_dimensions failed: %s (%d)",
651ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                strerror(-err), -err);
652ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        return err;
653ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    }
654ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar
655ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    err = native_window_set_buffers_format(
656ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar            mNativeWindow.get(),
657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.eColorFormat);
658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
660ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        ALOGE("native_window_set_buffers_format failed: %s (%d)",
661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                strerror(-err), -err);
662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
665e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang    if (mRotationDegrees != 0) {
666e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        uint32_t transform = 0;
667e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        switch (mRotationDegrees) {
668e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            case 0: transform = 0; break;
669e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            case 90: transform = HAL_TRANSFORM_ROT_90; break;
670e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            case 180: transform = HAL_TRANSFORM_ROT_180; break;
671e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            case 270: transform = HAL_TRANSFORM_ROT_270; break;
672e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            default: transform = 0; break;
673e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        }
674e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang
675e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        if (transform > 0) {
676e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            err = native_window_set_buffers_transform(
677e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang                    mNativeWindow.get(), transform);
678e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            if (err != 0) {
679e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang                ALOGE("native_window_set_buffers_transform failed: %s (%d)",
680e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang                        strerror(-err), -err);
681e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang                return err;
682e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            }
683e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        }
684e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang    }
685e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang
686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Set up the native window.
6873c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    OMX_U32 usage = 0;
6883c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
6893c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    if (err != 0) {
6905ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("querying usage flags from OMX IL component failed: %d", err);
6913c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        // XXX: Currently this error is logged, but not fatal.
6923c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        usage = 0;
6933c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    }
6945a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar    int omxUsage = usage;
6953c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis
6961713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang    if (mFlags & kFlagIsGrallocUsageProtected) {
697bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        usage |= GRALLOC_USAGE_PROTECTED;
698bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
699bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
700bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // Make sure to check whether either Stagefright or the video decoder
701bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // requested protected buffers.
702bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (usage & GRALLOC_USAGE_PROTECTED) {
703bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Verify that the ANativeWindow sends images directly to
704bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // SurfaceFlinger.
705bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        int queuesToNativeWindow = 0;
706bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->query(
707bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                mNativeWindow.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
708bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                &queuesToNativeWindow);
709bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != 0) {
710bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error authenticating native window: %d", err);
711bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
712bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
713bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (queuesToNativeWindow != 1) {
714bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("native window could not be authenticated");
715bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return PERMISSION_DENIED;
716bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
717bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
718bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
7195a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar    int consumerUsage = 0;
7205a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar    err = mNativeWindow->query(
7215a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            mNativeWindow.get(), NATIVE_WINDOW_CONSUMER_USAGE_BITS,
7225a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            &consumerUsage);
7235a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar    if (err != 0) {
7245a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        ALOGW("failed to get consumer usage bits. ignoring");
7255a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        err = 0;
7265a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar    }
7275a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
7285a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar    ALOGV("gralloc usage: %#x(OMX) => %#x(ACodec) + %#x(Consumer) = %#x",
7295a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            omxUsage, usage, consumerUsage, usage | consumerUsage);
7305a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar    usage |= consumerUsage;
731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_usage(
732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
7333c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis            usage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP);
734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
73629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err);
737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
740ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // Exits here for tunneled video playback codecs -- i.e. skips native window
741ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // buffer allocation step as this is managed by the tunneled OMX omponent
742ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // itself and explicitly sets def.nBufferCountActual to 0.
743ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    if (mTunneled) {
744ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        ALOGV("Tunneled Playback: skipping native window buffer allocation.");
745ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        def.nBufferCountActual = 0;
746ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        err = mOMX->setParameter(
747ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
748ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
749ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *minUndequeuedBuffers = 0;
750ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *bufferCount = 0;
751ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *bufferSize = 0;
752ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        return err;
753ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    }
754ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
755054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *minUndequeuedBuffers = 0;
756258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    err = mNativeWindow->query(
757258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
758054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (int *)minUndequeuedBuffers);
759258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
760258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    if (err != 0) {
76129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
762258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                strerror(-err), -err);
763258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        return err;
764258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
765258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
766e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // FIXME: assume that surface is controlled by app (native window
767e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // returns the number for the case when surface is not controlled by app)
7681faa41704e0b976e546321effcb09a85767d51baLajos Molnar    // FIXME2: This means that minUndeqeueudBufs can be 1 larger than reported
7691faa41704e0b976e546321effcb09a85767d51baLajos Molnar    // For now, try to allocate 1 more buffer, but don't fail if unsuccessful
770e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar
771e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // Use conservative allocation while also trying to reduce starvation
772e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //
773e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // 1. allocate at least nBufferCountMin + minUndequeuedBuffers - that is the
774e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //    minimum needed for the consumer to be able to work
775e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // 2. try to allocate two (2) additional buffers to reduce starvation from
776e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //    the consumer
7771faa41704e0b976e546321effcb09a85767d51baLajos Molnar    //    plus an extra buffer to account for incorrect minUndequeuedBufs
7781faa41704e0b976e546321effcb09a85767d51baLajos Molnar    for (OMX_U32 extraBuffers = 2 + 1; /* condition inside loop */; extraBuffers--) {
779e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        OMX_U32 newBufferCount =
780e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            def.nBufferCountMin + *minUndequeuedBuffers + extraBuffers;
781258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        def.nBufferCountActual = newBufferCount;
782258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        err = mOMX->setParameter(
783258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
784258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
785e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        if (err == OK) {
786e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            *minUndequeuedBuffers += extraBuffers;
787e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            break;
788e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        }
789e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar
790609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGW("[%s] setting nBufferCountActual to %u failed: %d",
791e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar                mComponentName.c_str(), newBufferCount, err);
792e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        /* exit condition */
793e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        if (extraBuffers == 0) {
794258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            return err;
795258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        }
796258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
797258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffer_count(
799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(), def.nBufferCountActual);
800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
80229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                -err);
804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
807054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferCount = def.nBufferCountActual;
808054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferSize =  def.nBufferSize;
809054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
810054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
811054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
812054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputBuffersFromNativeWindow() {
813054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
814054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
815054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
816054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
817054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
818e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    mNumUndequeuedBuffers = minUndequeuedBuffers;
819054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
8203298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia    if (!mStoreMetaDataInOutputBuffers) {
8213298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia        static_cast<Surface*>(mNativeWindow.get())
8223298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia                ->getIGraphicBufferProducer()->allowAllocation(true);
8233298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia    }
8243298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia
825609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Allocating %u buffers from a native window of size %u on "
826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         "output port",
827054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount, bufferSize);
828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Dequeue buffers and send them to OMX
830054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
8318ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev        ANativeWindowBuffer *buf;
8321e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
83429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
83974006804065941841883c4b46ee785070164023fJamie Gennis        BufferInfo info;
84074006804065941841883c4b46ee785070164023fJamie Gennis        info.mStatus = BufferInfo::OWNED_BY_US;
841054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(NULL /* data */, bufferSize /* capacity */);
84274006804065941841883c4b46ee785070164023fJamie Gennis        info.mGraphicBuffer = graphicBuffer;
84374006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].push(info);
84474006804065941841883c4b46ee785070164023fJamie Gennis
845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferId;
846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &bufferId);
848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
849609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGE("registering GraphicBuffer %u with OMX IL component failed: "
85074006804065941841883c4b46ee785070164023fJamie Gennis                 "%d", i, err);
851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
85474006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
85574006804065941841883c4b46ee785070164023fJamie Gennis
856609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGV("[%s] Registered graphic buffer with ID %u (pointer = %p)",
857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mComponentName.c_str(),
858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             bufferId, graphicBuffer.get());
859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelStart;
862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelEnd;
863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // If an error occurred while dequeuing we need to cancel any buffers
866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // that were dequeued.
867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelStart = 0;
86874006804065941841883c4b46ee785070164023fJamie Gennis        cancelEnd = mBuffers[kPortIndexOutput].size();
869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
870054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // Return the required minimum undequeued buffers to the native window.
871054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelStart = bufferCount - minUndequeuedBuffers;
872054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelEnd = bufferCount;
873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
8773fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        status_t error = cancelBufferToNativeWindow(info);
8783fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        if (err == 0) {
8793fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia            err = error;
8803fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        }
881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8833298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia    if (!mStoreMetaDataInOutputBuffers) {
8843298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia        static_cast<Surface*>(mNativeWindow.get())
8853298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia                ->getIGraphicBufferProducer()->allowAllocation(false);
8863298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia    }
8873298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia
888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
891054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputMetaDataBuffers() {
892054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
893054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
894054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
895054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
896054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
897e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    mNumUndequeuedBuffers = minUndequeuedBuffers;
898054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
899609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Allocating %u meta buffers on output port",
900054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount);
901054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
902054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    size_t totalSize = bufferCount * 8;
903054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mDealer[kPortIndexOutput] = new MemoryDealer(totalSize, "ACodec");
904054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
905054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // Dequeue buffers and send them to OMX
906054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
907054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo info;
908054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
909054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mGraphicBuffer = NULL;
910054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mDequeuedAt = mDequeueCounter;
911054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
912054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        sp<IMemory> mem = mDealer[kPortIndexOutput]->allocate(
913054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                sizeof(struct VideoDecoderOutputMetaData));
914054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(mem.get() != NULL);
915054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(mem->pointer(), mem->size());
916054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
917054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // we use useBuffer for metadata regardless of quirks
918054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        err = mOMX->useBuffer(
919054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mNode, kPortIndexOutput, mem, &info.mBufferID);
920054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
921054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        mBuffers[kPortIndexOutput].push(info);
922054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
923609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGV("[%s] allocated meta buffer with ID %u (pointer = %p)",
924054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mComponentName.c_str(), info.mBufferID, mem->pointer());
925054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
926054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
927054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mMetaDataBuffersToSubmit = bufferCount - minUndequeuedBuffers;
928054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
929054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
930054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
931054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::submitOutputMetaDataBuffer() {
932054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mStoreMetaDataInOutputBuffers);
933054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mMetaDataBuffersToSubmit == 0)
934054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return OK;
935054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
936054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *info = dequeueBufferFromNativeWindow();
937054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (info == NULL)
938054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return ERROR_IO;
939054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
940609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] submitting output meta buffer ID %u for graphic buffer %p",
941054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          mComponentName.c_str(), info->mBufferID, info->mGraphicBuffer.get());
942054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
943054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    --mMetaDataBuffersToSubmit;
944054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK_EQ(mOMX->fillBuffer(mNode, info->mBufferID),
945054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             (status_t)OK);
946054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
947054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
948054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return OK;
949054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
950054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
951f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
954609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Calling cancelBuffer on buffer %u",
955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mComponentName.c_str(), info->mBufferID);
956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int err = mNativeWindow->cancelBuffer(
9581e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        mNativeWindow.get(), info->mGraphicBuffer.get(), -1);
959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9603fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia    ALOGW_IF(err != 0, "[%s] can not return buffer %u to native window",
9613fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia            mComponentName.c_str(), info->mBufferID);
962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9653fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia    return err;
966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
968f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
9698ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev    ANativeWindowBuffer *buf;
970054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mNativeWindow.get() != NULL);
971ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
972ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    if (mTunneled) {
973ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        ALOGW("dequeueBufferFromNativeWindow() should not be called in tunnel"
974ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad              " video playback mode mode!");
975ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        return NULL;
976ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    }
977ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
9781e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    if (native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf) != 0) {
97929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("dequeueBuffer failed.");
980c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber        return NULL;
981c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
983054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *oldest = NULL;
984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
988054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mGraphicBuffer != NULL &&
989054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            info->mGraphicBuffer->handle == buf->handle) {
990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus,
991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (int)BufferInfo::OWNED_BY_NATIVE_WINDOW);
992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
997054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
998054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW &&
999054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (oldest == NULL ||
1000054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             // avoid potential issues from counter rolling over
1001054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mDequeueCounter - info->mDequeuedAt >
1002054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    mDequeueCounter - oldest->mDequeuedAt)) {
1003054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            oldest = info;
1004054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
1005054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1006054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1007054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (oldest) {
1008054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(mStoreMetaDataInOutputBuffers);
1009054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1010054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // discard buffer in LRU info and replace with new buffer
1011054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mGraphicBuffer = new GraphicBuffer(buf, false);
1012054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mStatus = BufferInfo::OWNED_BY_US;
1013054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1014d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        mOMX->updateGraphicBufferInMeta(
1015d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                mNode, kPortIndexOutput, oldest->mGraphicBuffer,
1016d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                oldest->mBufferID);
1017054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1018d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        VideoDecoderOutputMetaData *metaData =
1019d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar            reinterpret_cast<VideoDecoderOutputMetaData *>(
1020d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                    oldest->mData->base());
1021d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        CHECK_EQ(metaData->eType, kMetadataBufferTypeGrallocSource);
1022d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar
1023d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
1024ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                (unsigned)(oldest - &mBuffers[kPortIndexOutput][0]),
1025054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mDequeueCounter - oldest->mDequeuedAt,
1026d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                metaData->pHandle,
1027d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                oldest->mGraphicBuffer->handle, oldest->mData->base());
1028054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1029054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return oldest;
1030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
1033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
1035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1037f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
1038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[portIndex].size(); i-- > 0;) {
1039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, freeBuffer(portIndex, i));
1040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDealer[portIndex].clear();
1043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1047349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huberstatus_t ACodec::freeOutputBuffersNotOwnedByComponent() {
1048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
1049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
1050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
1051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10522ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // At this time some buffers may still be with the component
10532ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // or being drained.
10542ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT &&
10552ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar            info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) {
1056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK, freeBuffer(kPortIndexOutput, i));
1057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1063f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
1064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
1065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(info->mStatus == BufferInfo::OWNED_BY_US
1067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
1068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput && mNativeWindow != NULL
1070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && info->mStatus == BufferInfo::OWNED_BY_US) {
10713fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        cancelBufferToNativeWindow(info);
1072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(mOMX->freeBuffer(
1075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, portIndex, info->mBufferID),
1076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
1077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mBuffers[portIndex].removeAt(i);
1079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1081f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1083f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::findBufferByID(
1084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        uint32_t portIndex, IOMX::buffer_id bufferID,
1085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ssize_t *index) {
1086f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
1087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
1088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1089f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mBufferID == bufferID) {
1090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (index != NULL) {
1091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                *index = i;
1092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
1094f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1095f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
1098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
1100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
11025778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setComponentRole(
1103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        bool isEncoder, const char *mime) {
1104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    struct MimeToRole {
1105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime;
1106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *decoderRole;
1107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *encoderRole;
1108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
1109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const MimeToRole kMimeToRole[] = {
1111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG,
1112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.mp3", "audio_encoder.mp3" },
11132944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
11142944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp1", "audio_encoder.mp1" },
11152944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
11162944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp2", "audio_encoder.mp2" },
1117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_NB,
1118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrnb", "audio_encoder.amrnb" },
1119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_WB,
1120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrwb", "audio_encoder.amrwb" },
1121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AAC,
1122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.aac", "audio_encoder.aac" },
1123729de186450f78c099637e1fce743fe531862c52Andreas Huber        { MEDIA_MIMETYPE_AUDIO_VORBIS,
1124729de186450f78c099637e1fce743fe531862c52Andreas Huber            "audio_decoder.vorbis", "audio_encoder.vorbis" },
1125bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian        { MEDIA_MIMETYPE_AUDIO_OPUS,
1126bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian            "audio_decoder.opus", "audio_encoder.opus" },
1127c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_MLAW,
1128c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" },
1129c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_ALAW,
1130c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711alaw", "audio_encoder.g711alaw" },
1131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_AVC,
1132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.avc", "video_encoder.avc" },
11332472b1c0d63454e5d90a982bd6c555de6c3127bdRachad        { MEDIA_MIMETYPE_VIDEO_HEVC,
11342472b1c0d63454e5d90a982bd6c555de6c3127bdRachad            "video_decoder.hevc", "video_encoder.hevc" },
1135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_MPEG4,
1136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.mpeg4", "video_encoder.mpeg4" },
1137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_H263,
1138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.h263", "video_encoder.h263" },
113994705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP8,
114094705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp8", "video_encoder.vp8" },
114194705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP9,
114294705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp9", "video_encoder.vp9" },
1143ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        { MEDIA_MIMETYPE_AUDIO_RAW,
1144ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            "audio_decoder.raw", "audio_encoder.raw" },
11452f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        { MEDIA_MIMETYPE_AUDIO_FLAC,
11462f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            "audio_decoder.flac", "audio_encoder.flac" },
1147ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        { MEDIA_MIMETYPE_AUDIO_MSGSM,
1148ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen            "audio_decoder.gsm", "audio_encoder.gsm" },
1149774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu        { MEDIA_MIMETYPE_VIDEO_MPEG2,
1150774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu            "video_decoder.mpeg2", "video_encoder.mpeg2" },
115197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        { MEDIA_MIMETYPE_AUDIO_AC3,
115297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            "audio_decoder.ac3", "audio_encoder.ac3" },
11538a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        { MEDIA_MIMETYPE_AUDIO_EAC3,
11548a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            "audio_decoder.eac3", "audio_encoder.eac3" },
1155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
1156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const size_t kNumMimeToRole =
1158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
1159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    size_t i;
1161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (i = 0; i < kNumMimeToRole; ++i) {
1162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcasecmp(mime, kMimeToRole[i].mime)) {
1163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (i == kNumMimeToRole) {
11685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_UNSUPPORTED;
1169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    const char *role =
1172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        isEncoder ? kMimeToRole[i].encoderRole
1173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                  : kMimeToRole[i].decoderRole;
1174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (role != NULL) {
1176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_PARAM_COMPONENTROLETYPE roleParams;
1177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        InitOMXParams(&roleParams);
1178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        strncpy((char *)roleParams.cRole,
1180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                role, OMX_MAX_STRINGNAME_SIZE - 1);
1181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
1183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->setParameter(
1185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamStandardComponentRole,
1186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &roleParams, sizeof(roleParams));
1187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
11895ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("[%s] Failed to set standard component role '%s'.",
1190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 mComponentName.c_str(), role);
11915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
1193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
11955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
1197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
11995778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::configureCodec(
1200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime, const sp<AMessage> &msg) {
12015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t encoder;
12025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("encoder", &encoder)) {
12035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        encoder = false;
12045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1206e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    sp<AMessage> inputFormat = new AMessage();
12074e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    sp<AMessage> outputFormat = mNotify->dup(); // will use this for kWhatOutputFormatChanged
1208e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
12095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mIsEncoder = encoder;
1210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
12118db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu
12125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setComponentRole(encoder /* isEncoder */, mime);
12135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
12155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
12165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
12175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitRate = 0;
12192f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    // FLAC encoder doesn't need a bitrate, other encoders do
12202f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
12212f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            && !msg->findInt32("bitrate", &bitRate)) {
12225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
12235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
12245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1225d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    int32_t storeMeta;
1226d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (encoder
1227d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && msg->findInt32("store-metadata-in-buffers", &storeMeta)
1228d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && storeMeta != 0) {
1229d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE);
1230d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1231d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (err != OK) {
1232308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              ALOGE("[%s] storeMetaDataInBuffers (input) failed w/ err %d",
1233308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    mComponentName.c_str(), err);
1234d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1235308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              return err;
1236308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang          }
1237308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang      }
1238d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1239308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t prependSPSPPS = 0;
12403a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    if (encoder
12413a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
12423a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && prependSPSPPS != 0) {
12433a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        OMX_INDEXTYPE index;
12443a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        err = mOMX->getExtensionIndex(
12453a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                mNode,
12463a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                "OMX.google.android.index.prependSPSPPSToIDRFrames",
12473a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                &index);
12483a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
12493a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err == OK) {
12503a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            PrependSPSPPSToIDRFramesParams params;
12513a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            InitOMXParams(&params);
12523a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            params.bEnable = OMX_TRUE;
12533a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
12543a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            err = mOMX->setParameter(
12553a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                    mNode, index, &params, sizeof(params));
12563a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
12573a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
12583a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err != OK) {
12593a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            ALOGE("Encoder could not be configured to emit SPS/PPS before "
12603a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                  "IDR frames. (err %d)", err);
12613a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
12623a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            return err;
12633a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
12643a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    }
12653a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
1266308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // Only enable metadata mode on encoder output if encoder can prepend
1267308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // sps/pps to idr frames, since in metadata mode the bitstream is in an
1268308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // opaque handle, to which we don't have access.
1269308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t video = !strncasecmp(mime, "video/", 6);
12708db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    mIsVideo = video;
1271308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (encoder && video) {
1272308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS
1273308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && msg->findInt32("store-metadata-in-buffers-output", &storeMeta)
1274308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && storeMeta != 0);
1275308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1276308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, enable);
1277308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1278308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        if (err != OK) {
1279308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            ALOGE("[%s] storeMetaDataInBuffers (output) failed w/ err %d",
1280308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                mComponentName.c_str(), err);
1281308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = 0;
1282308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        } else {
1283308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = enable;
1284308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        }
1285a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
1286a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (!msg->findInt64(
1287a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    "repeat-previous-frame-after",
1288a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    &mRepeatFrameDelayUs)) {
1289a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            mRepeatFrameDelayUs = -1ll;
1290a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
129194ee4b708acfa941581160b267afb79192b1d816Chong Zhang
129294ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (!msg->findInt64("max-pts-gap-to-encoder", &mMaxPtsGapUs)) {
12932c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mMaxPtsGapUs = -1ll;
12942c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
12952c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
129637b2b389139ed638831e49708c947863eef631efRonghua Wu        if (!msg->findFloat("max-fps-to-encoder", &mMaxFps)) {
129737b2b389139ed638831e49708c947863eef631efRonghua Wu            mMaxFps = -1;
129837b2b389139ed638831e49708c947863eef631efRonghua Wu        }
129937b2b389139ed638831e49708c947863eef631efRonghua Wu
13002c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (!msg->findInt64("time-lapse", &mTimePerCaptureUs)) {
13012c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mTimePerCaptureUs = -1ll;
130294ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
130372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
130472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (!msg->findInt32(
130572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    "create-input-buffers-suspended",
130672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    (int32_t*)&mCreateInputBuffersSuspended)) {
130772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mCreateInputBuffersSuspended = false;
130872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
1309308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    }
1310308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
13113a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar    // NOTE: we only use native window for video decoders
1312054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    sp<RefBase> obj;
13130d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    bool haveNativeWindow = msg->findObject("native-window", &obj)
13143a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            && obj != NULL && video && !encoder;
1315054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mStoreMetaDataInOutputBuffers = false;
1316e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if (video && !encoder) {
1317e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        inputFormat->setInt32("adaptive-playback", false);
13181713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang
13191713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        int32_t usageProtected;
13201713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        if (msg->findInt32("protected", &usageProtected) && usageProtected) {
13211713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            if (!haveNativeWindow) {
13221713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang                ALOGE("protected output buffers must be sent to an ANativeWindow");
13231713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang                return PERMISSION_DENIED;
13241713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            }
13251713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            mFlags |= kFlagIsGrallocUsageProtected;
13261713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
13271713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        }
1328e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
13293a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar    if (haveNativeWindow) {
13301de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar        sp<ANativeWindow> nativeWindow =
13311de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar            static_cast<ANativeWindow *>(static_cast<Surface *>(obj.get()));
13325a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
13336597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        // START of temporary support for automatic FRC - THIS WILL BE REMOVED
13346597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        int32_t autoFrc;
13356597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        if (msg->findInt32("auto-frc", &autoFrc)) {
13366597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            bool enabled = autoFrc;
13376597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            OMX_CONFIG_BOOLEANTYPE config;
13386597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            InitOMXParams(&config);
13396597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            config.bEnabled = (OMX_BOOL)enabled;
13406597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            status_t temp = mOMX->setConfig(
13416597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                    mNode, (OMX_INDEXTYPE)OMX_IndexConfigAutoFramerateConversion,
13426597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                    &config, sizeof(config));
13436597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            if (temp == OK) {
13446597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                outputFormat->setInt32("auto-frc", enabled);
13456597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            } else if (enabled) {
13466597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                ALOGI("codec does not support requested auto-frc (err %d)", temp);
13476597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            }
13486597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        }
13496597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        // END of temporary support for automatic FRC
13506597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar
13515a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        int32_t tunneled;
13525a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        if (msg->findInt32("feature-tunneled-playback", &tunneled) &&
13535a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            tunneled != 0) {
13545a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            ALOGI("Configuring TUNNELED video playback.");
1355ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            mTunneled = true;
13565a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
135797827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad            int32_t audioHwSync = 0;
135897827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad            if (!msg->findInt32("audio-hw-sync", &audioHwSync)) {
13595a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGW("No Audio HW Sync provided for video tunnel");
13605a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            }
13615a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            err = configureTunneledVideoPlayback(audioHwSync, nativeWindow);
13625a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (err != OK) {
136397827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad                ALOGE("configureTunneledVideoPlayback(%d,%p) failed!",
13645a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        audioHwSync, nativeWindow.get());
13655a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                return err;
1366fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
1367fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1368d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            int32_t maxWidth = 0, maxHeight = 0;
1369d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            if (msg->findInt32("max-width", &maxWidth) &&
1370d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    msg->findInt32("max-height", &maxHeight)) {
1371d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad
1372d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                err = mOMX->prepareForAdaptivePlayback(
1373d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                        mNode, kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight);
1374d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                if (err != OK) {
1375d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    ALOGW("[%s] prepareForAdaptivePlayback failed w/ err %d",
1376d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                            mComponentName.c_str(), err);
13773a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    // allow failure
13783a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    err = OK;
1379d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                } else {
1380d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("max-width", maxWidth);
1381d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("max-height", maxHeight);
1382d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("adaptive-playback", true);
1383d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                }
1384d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            }
13855a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        } else {
1386ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            ALOGV("Configuring CPU controlled video playback.");
1387ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            mTunneled = false;
1388ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
13893fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // Explicity reset the sideband handle of the window for
13903fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // non-tunneled video in case the window was previously used
13913fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // for a tunneled video playback.
13923fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            err = native_window_set_sideband_stream(nativeWindow.get(), NULL);
13933fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            if (err != OK) {
13943fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad                ALOGE("set_sideband_stream(NULL) failed! (err %d).", err);
13953fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad                return err;
13963fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            }
13973fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad
13985a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            // Always try to enable dynamic output buffers on native surface
13995a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            err = mOMX->storeMetaDataInBuffers(
14005a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    mNode, kPortIndexOutput, OMX_TRUE);
14015a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (err != OK) {
14025a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d",
1403fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        mComponentName.c_str(), err);
1404e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
14055a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // if adaptive playback has been requested, try JB fallback
14065a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // NOTE: THIS FALLBACK MECHANISM WILL BE REMOVED DUE TO ITS
14075a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // LARGE MEMORY REQUIREMENT
14085a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
14095a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // we will not do adaptive playback on software accessed
14105a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // surfaces as they never had to respond to changes in the
14115a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // crop window, and we don't trust that they will be able to.
14125a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                int usageBits = 0;
14135a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                bool canDoAdaptivePlayback;
14145a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
14155a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                if (nativeWindow->query(
14165a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        nativeWindow.get(),
14175a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        NATIVE_WINDOW_CONSUMER_USAGE_BITS,
14185a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        &usageBits) != OK) {
14195a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    canDoAdaptivePlayback = false;
14205a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                } else {
14215a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    canDoAdaptivePlayback =
14225a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        (usageBits &
14235a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                                (GRALLOC_USAGE_SW_READ_MASK |
14245a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                                 GRALLOC_USAGE_SW_WRITE_MASK)) == 0;
14255a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                }
14265a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
14275a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                int32_t maxWidth = 0, maxHeight = 0;
14285a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                if (canDoAdaptivePlayback &&
14295a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        msg->findInt32("max-width", &maxWidth) &&
14305a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        msg->findInt32("max-height", &maxHeight)) {
14315a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    ALOGV("[%s] prepareForAdaptivePlayback(%dx%d)",
14325a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mComponentName.c_str(), maxWidth, maxHeight);
14335a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
14345a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    err = mOMX->prepareForAdaptivePlayback(
14355a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mNode, kPortIndexOutput, OMX_TRUE, maxWidth,
14365a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            maxHeight);
14375a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    ALOGW_IF(err != OK,
14385a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            "[%s] prepareForAdaptivePlayback failed w/ err %d",
14395a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mComponentName.c_str(), err);
14405a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
14415a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    if (err == OK) {
14425a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("max-width", maxWidth);
14435a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("max-height", maxHeight);
14445a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("adaptive-playback", true);
14455a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    }
1446e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
14475a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // allow failure
14485a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                err = OK;
14495a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            } else {
14505a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGV("[%s] storeMetaDataInBuffers succeeded",
14515a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        mComponentName.c_str());
14525a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                mStoreMetaDataInOutputBuffers = true;
14535a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                inputFormat->setInt32("adaptive-playback", true);
1454fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
14550167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber
14565a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            int32_t push;
14575a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (msg->findInt32("push-blank-buffers-on-shutdown", &push)
14585a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    && push != 0) {
14595a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
14605a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            }
14610167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        }
1462e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang
1463e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        int32_t rotationDegrees;
1464e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        if (msg->findInt32("rotation-degrees", &rotationDegrees)) {
1465e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            mRotationDegrees = rotationDegrees;
1466e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        } else {
1467e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            mRotationDegrees = 0;
1468e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        }
1469054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1470054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1471308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (video) {
14723a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // determine need for software renderer
14733a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        bool usingSwRenderer = false;
14743a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (haveNativeWindow && mComponentName.startsWith("OMX.google.")) {
14753a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            usingSwRenderer = true;
14763a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            haveNativeWindow = false;
14773a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
14783a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
14795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (encoder) {
14805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupVideoEncoder(mime, msg);
14815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
14820d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            err = setupVideoDecoder(mime, msg, haveNativeWindow);
14835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14843a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
14853a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (err != OK) {
14863a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            return err;
14873a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
14883a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
14893a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (haveNativeWindow) {
14901de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar            mNativeWindow = static_cast<Surface *>(obj.get());
14911de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar            CHECK(mNativeWindow != NULL);
14923a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
14933a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            native_window_set_scaling_mode(
14943a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    mNativeWindow.get(), NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
14953a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
14963a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
14973a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // initialize native window now to get actual output format
14983a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // TODO: this is needed for some encoders even though they don't use native window
14993a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        CHECK_EQ((status_t)OK, initNativeWindow());
15003a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
15013a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // fallback for devices that do not handle flex-YUV for native buffers
15023a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (haveNativeWindow) {
15033a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            int32_t requestedColorFormat = OMX_COLOR_FormatUnused;
15043a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            if (msg->findInt32("color-format", &requestedColorFormat) &&
15053a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    requestedColorFormat == OMX_COLOR_FormatYUV420Flexible) {
15063a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                CHECK_EQ(getPortFormat(kPortIndexOutput, outputFormat), (status_t)OK);
15073a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                int32_t colorFormat = OMX_COLOR_FormatUnused;
15083a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                OMX_U32 flexibleEquivalent = OMX_COLOR_FormatUnused;
15093a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                CHECK(outputFormat->findInt32("color-format", &colorFormat));
15103a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                ALOGD("[%s] Requested output format %#x and got %#x.",
15113a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        mComponentName.c_str(), requestedColorFormat, colorFormat);
15123a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                if (!isFlexibleColorFormat(
15133a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                                mOMX, mNode, colorFormat, haveNativeWindow, &flexibleEquivalent)
15143a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        || flexibleEquivalent != (OMX_U32)requestedColorFormat) {
15153a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    // device did not handle flex-YUV request for native window, fall back
15163a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    // to SW renderer
15173a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    ALOGI("[%s] Falling back to software renderer", mComponentName.c_str());
15183a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    mNativeWindow.clear();
15193a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    haveNativeWindow = false;
15203a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    usingSwRenderer = true;
15213a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    if (mStoreMetaDataInOutputBuffers) {
15223a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, OMX_FALSE);
15233a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        mStoreMetaDataInOutputBuffers = false;
15243a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        // TODO: implement adaptive-playback support for bytebuffer mode.
15253a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        // This is done by SW codecs, but most HW codecs don't support it.
15263a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        inputFormat->setInt32("adaptive-playback", false);
15273a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
15283a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    if (err == OK) {
15293a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        err = mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
15303a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
15313a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    if (mFlags & kFlagIsGrallocUsageProtected) {
15323a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        // fallback is not supported for protected playback
15333a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        err = PERMISSION_DENIED;
15343a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    } else if (err == OK) {
15353a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        err = setupVideoDecoder(mime, msg, false);
15363a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
15373a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                }
15383a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            }
15393a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
15403a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
15413a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (usingSwRenderer) {
15423a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            outputFormat->setInt32("using-sw-renderer", 1);
15433a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
154442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
154542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        int32_t numChannels, sampleRate;
154642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        if (!msg->findInt32("channel-count", &numChannels)
154742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
154842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // Since we did not always check for these, leave them optional
154942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // and have the decoder figure it all out.
155042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = OK;
155142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        } else {
155242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = setupRawAudioFormat(
155342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    encoder ? kPortIndexInput : kPortIndexOutput,
155442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    sampleRate,
155542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    numChannels);
155642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        }
1557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
1558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t numChannels, sampleRate;
15595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)
15605778822d86b0337407514b9372562b86edfa91cdAndreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
15615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
15625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
1563aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            int32_t isADTS, aacProfile;
1564b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            int32_t sbrMode;
15658045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            int32_t maxOutputChannelCount;
15662965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            int32_t pcmLimiterEnable;
15678045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            drcParams_t drc;
1568ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            if (!msg->findInt32("is-adts", &isADTS)) {
1569ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                isADTS = 0;
1570ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
1571aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (!msg->findInt32("aac-profile", &aacProfile)) {
1572aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                aacProfile = OMX_AUDIO_AACObjectNull;
1573aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
1574b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            if (!msg->findInt32("aac-sbr-mode", &sbrMode)) {
1575b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                sbrMode = -1;
1576b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            }
1577ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
15788045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-max-output-channel_count", &maxOutputChannelCount)) {
15798045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                maxOutputChannelCount = -1;
15808045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
15812965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            if (!msg->findInt32("aac-pcm-limiter-enable", &pcmLimiterEnable)) {
15822965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                // value is unknown
15832965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                pcmLimiterEnable = -1;
15842965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            }
15858045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-encoded-target-level", &drc.encodedTargetLevel)) {
15868045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
15878045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.encodedTargetLevel = -1;
15888045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
15898045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-cut-level", &drc.drcCut)) {
15908045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
15918045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.drcCut = -1;
15928045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
15938045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-boost-level", &drc.drcBoost)) {
15948045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
15958045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.drcBoost = -1;
15968045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
15978045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-heavy-compression", &drc.heavyCompression)) {
15988045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
15998045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.heavyCompression = -1;
16008045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
16018045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-target-ref-level", &drc.targetRefLevel)) {
16028045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
16038045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.targetRefLevel = -1;
16048045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
16058045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi
1606ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            err = setupAACCodec(
16074471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    encoder, numChannels, sampleRate, bitRate, aacProfile,
16082965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                    isADTS != 0, sbrMode, maxOutputChannelCount, drc,
16092965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                    pcmLimiterEnable);
16105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
1611729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
16125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
1613729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
16145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
1615729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
1616729de186450f78c099637e1fce743fe531862c52Andreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
1617729de186450f78c099637e1fce743fe531862c52Andreas Huber        // These are PCM-like formats with a fixed sample rate but
1618729de186450f78c099637e1fce743fe531862c52Andreas Huber        // a variable number of channels.
1619729de186450f78c099637e1fce743fe531862c52Andreas Huber
1620729de186450f78c099637e1fce743fe531862c52Andreas Huber        int32_t numChannels;
16215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)) {
16225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
16235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
162417c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            int32_t sampleRate;
162517c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            if (!msg->findInt32("sample-rate", &sampleRate)) {
162617c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen                sampleRate = 8000;
162717c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            }
162817c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            err = setupG711Codec(encoder, sampleRate, numChannels);
16295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16302f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
1631ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        int32_t numChannels = 0, sampleRate = 0, compressionLevel = -1;
16322f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (encoder &&
16332f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                (!msg->findInt32("channel-count", &numChannels)
16342f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                        || !msg->findInt32("sample-rate", &sampleRate))) {
16352f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("missing channel count or sample rate for FLAC encoder");
16362f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            err = INVALID_OPERATION;
16372f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        } else {
16382f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            if (encoder) {
1639516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                if (!msg->findInt32(
1640cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                            "complexity", &compressionLevel) &&
1641cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                    !msg->findInt32(
1642516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                            "flac-compression-level", &compressionLevel)) {
1643cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                    compressionLevel = 5; // default FLAC compression level
16442f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel < 0) {
1645516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1646516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 0",
1647516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
16482f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 0;
16492f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel > 8) {
1650516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1651516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 8",
1652516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
16532f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 8;
16542f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                }
16552f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            }
1656516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            err = setupFlacCodec(
1657516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    encoder, numChannels, sampleRate, compressionLevel);
16582f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
1659ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
1660ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        int32_t numChannels, sampleRate;
1661ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        if (encoder
1662ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("channel-count", &numChannels)
1663ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
1664ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = INVALID_OPERATION;
1665ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        } else {
1666ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
1667ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        }
166897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AC3)) {
166997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t numChannels;
167097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t sampleRate;
167197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        if (!msg->findInt32("channel-count", &numChannels)
167297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                || !msg->findInt32("sample-rate", &sampleRate)) {
167397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = INVALID_OPERATION;
167497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        } else {
167597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = setupAC3Codec(encoder, numChannels, sampleRate);
167697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        }
16778a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_EAC3)) {
16788a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        int32_t numChannels;
16798a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        int32_t sampleRate;
16808a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        if (!msg->findInt32("channel-count", &numChannels)
16818a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                || !msg->findInt32("sample-rate", &sampleRate)) {
16828a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            err = INVALID_OPERATION;
16838a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        } else {
16848a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            err = setupEAC3Codec(encoder, numChannels, sampleRate);
16858a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        }
16865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1687729de186450f78c099637e1fce743fe531862c52Andreas Huber
16884471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    if (err != OK) {
16894471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber        return err;
16904471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    }
16914471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber
16928b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
16938b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderDelay = 0;
16948b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
16959806555d3930be43e11106281dee354820ac1c88Andreas Huber
16968b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
16978b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderPadding = 0;
16988b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
16998b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen
17009806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (msg->findInt32("channel-mask", &mChannelMask)) {
17019806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = true;
17029806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else {
17039806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = false;
17049806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
17059806555d3930be43e11106281dee354820ac1c88Andreas Huber
1706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t maxInputSize;
1707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (msg->findInt32("max-input-size", &maxInputSize)) {
17085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
1709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
17105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
1711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
17125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17138b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    int32_t priority;
17148b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    if (msg->findInt32("priority", &priority)) {
17158b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu        err = setPriority(priority);
17168b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    }
17178b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu
1718ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    int32_t rateInt = -1;
1719ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    float rateFloat = -1;
1720ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (!msg->findFloat("operating-rate", &rateFloat)) {
1721ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        msg->findInt32("operating-rate", &rateInt);
1722ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        rateFloat = (float)rateInt;  // 16MHz (FLINTMAX) is OK for upper bound.
1723ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
1724ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (rateFloat > 0) {
1725ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        err = setOperatingRate(rateFloat, video);
1726ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
1727ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu
17284e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    mBaseOutputFormat = outputFormat;
17294e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar
1730e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ(getPortFormat(kPortIndexInput, inputFormat), (status_t)OK);
1731e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ(getPortFormat(kPortIndexOutput, outputFormat), (status_t)OK);
1732e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mInputFormat = inputFormat;
1733e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mOutputFormat = outputFormat;
1734e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
17355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
1736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
17388b806ea894ca098366629458bfdd1df4866afcdfRonghua Wustatus_t ACodec::setPriority(int32_t priority) {
17398b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    if (priority < 0) {
17408b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu        return BAD_VALUE;
17418b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    }
17428b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    OMX_PARAM_U32TYPE config;
17438b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    InitOMXParams(&config);
17448b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    config.nU32 = (OMX_U32)priority;
17458b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    status_t temp = mOMX->setConfig(
17468b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu            mNode, (OMX_INDEXTYPE)OMX_IndexConfigPriority,
17478b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu            &config, sizeof(config));
17488b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    if (temp != OK) {
17498b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu        ALOGI("codec does not support config priority (err %d)", temp);
17508b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    }
17518b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    return OK;
17528b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu}
17538b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu
1754ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wustatus_t ACodec::setOperatingRate(float rateFloat, bool isVideo) {
1755ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (rateFloat < 0) {
1756ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        return BAD_VALUE;
1757ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
1758ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    OMX_U32 rate;
1759ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (isVideo) {
1760ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        if (rateFloat > 65535) {
1761ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            return BAD_VALUE;
1762ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        }
1763ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        rate = (OMX_U32)(rateFloat * 65536.0f + 0.5f);
1764ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    } else {
1765ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        if (rateFloat > UINT_MAX) {
1766ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            return BAD_VALUE;
1767ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        }
1768ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        rate = (OMX_U32)(rateFloat);
1769ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
1770ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    OMX_PARAM_U32TYPE config;
1771ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    InitOMXParams(&config);
1772ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    config.nU32 = rate;
1773ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    status_t err = mOMX->setConfig(
1774ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            mNode, (OMX_INDEXTYPE)OMX_IndexConfigOperatingRate,
1775ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            &config, sizeof(config));
1776ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (err != OK) {
1777ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        ALOGI("codec does not support config operating rate (err %d)", err);
1778ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
1779ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    return OK;
1780ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu}
1781ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu
1782f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
1783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
1785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
1786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (def.nBufferSize >= size) {
1795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
1796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nBufferSize = size;
1799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
1801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->getParameter(
1808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(def.nBufferSize >= size);
1815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
18195778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::selectAudioPortFormat(
18205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
18215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_AUDIO_PARAM_PORTFORMATTYPE format;
18225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&format);
18235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    format.nPortIndex = portIndex;
18255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (OMX_U32 index = 0;; ++index) {
18265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        format.nIndex = index;
18275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
18295778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioPortFormat,
18305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &format, sizeof(format));
18315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
18335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
18345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (format.eEncoding == desiredFormat) {
18375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
18385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
18425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format));
18435778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
18445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18455778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAACCodec(
1846aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        bool encoder, int32_t numChannels, int32_t sampleRate,
18478045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        int32_t bitRate, int32_t aacProfile, bool isADTS, int32_t sbrMode,
18482965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang        int32_t maxOutputChannelCount, const drcParams_t& drc,
18492965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang        int32_t pcmLimiterEnable) {
1850ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (encoder && isADTS) {
1851ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return -EINVAL;
1852ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
1853ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
18545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setupRawAudioFormat(
18555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
18565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sampleRate,
18575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            numChannels);
18585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (encoder) {
18645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
18655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
18675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
18685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
18715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
18725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = kPortIndexOutput;
18735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
18755778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
18765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
18785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
18795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.bFlagErrorConcealment = OMX_TRUE;
18825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
18835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
18855778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
18865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
18885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
18895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
18925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&profile);
18935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nPortIndex = kPortIndexOutput;
18945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
18965778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
18975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
18995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
19005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nChannels = numChannels;
19035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eChannelMode =
19055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (numChannels == 1)
19065778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
19075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nSampleRate = sampleRate;
19095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nBitRate = bitRate;
19105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAudioBandWidth = 0;
19115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nFrameLength = 0;
19125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACtools = OMX_AUDIO_AACToolAll;
19135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACERtools = OMX_AUDIO_AACERNone;
1914aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
19155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
1916b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        switch (sbrMode) {
1917b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 0:
1918b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // disable sbr
1919b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
1920b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
1921b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
1922b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 1:
1923b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable single-rate sbr
1924b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
1925b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
1926b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
1927b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 2:
1928b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable dual-rate sbr
1929b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
1930b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
1931b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
1932b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case -1:
1933b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable both modes -> the codec will decide which mode should be used
1934b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
1935b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
1936b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
1937b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        default:
1938b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // unsupported sbr mode
1939b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            return BAD_VALUE;
1940b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        }
1941b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi
19425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
19445778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
19455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
19475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
19485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_AUDIO_PARAM_AACPROFILETYPE profile;
1954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&profile);
1955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nPortIndex = kPortIndexInput;
1956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
19575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
1958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
1959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nChannels = numChannels;
1965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nSampleRate = sampleRate;
1966ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1967ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    profile.eAACStreamFormat =
1968ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        isADTS
1969ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            ? OMX_AUDIO_AACStreamFormatMP4ADTS
1970ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            : OMX_AUDIO_AACStreamFormatMP4FF;
1971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
19728045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    OMX_AUDIO_PARAM_ANDROID_AACPRESENTATIONTYPE presentation;
19738045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nMaxOutputChannels = maxOutputChannelCount;
19748045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nDrcCut = drc.drcCut;
19758045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nDrcBoost = drc.drcBoost;
19768045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nHeavyCompression = drc.heavyCompression;
19778045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nTargetReferenceLevel = drc.targetRefLevel;
19788045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nEncodedTargetLevel = drc.encodedTargetLevel;
19792965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang    presentation.nPCMLimiterEnable = pcmLimiterEnable;
19808045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi
19818045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    status_t res = mOMX->setParameter(mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
19828045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    if (res == OK) {
19838045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        // optional parameters, will not cause configuration failure
19848045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        mOMX->setParameter(mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAacPresentation,
19858045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                &presentation, sizeof(presentation));
19868045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    } else {
19878045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        ALOGW("did not set AudioAndroidAacPresentation due to error %d when setting AudioAac", res);
19888045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    }
19898045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    return res;
19905778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
199297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryustatus_t ACodec::setupAC3Codec(
199397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        bool encoder, int32_t numChannels, int32_t sampleRate) {
199497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    status_t err = setupRawAudioFormat(
199597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
199697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
199797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
199897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
199997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
200097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
200197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (encoder) {
200297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        ALOGW("AC3 encoding is not supported.");
200397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return INVALID_OPERATION;
200497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
200597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
200697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    OMX_AUDIO_PARAM_ANDROID_AC3TYPE def;
200797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    InitOMXParams(&def);
200897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nPortIndex = kPortIndexInput;
200997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
201097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    err = mOMX->getParameter(
201197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
201297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
201397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
201497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
201597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
201697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
201797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
201897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
201997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
202097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nChannels = numChannels;
202197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nSampleRate = sampleRate;
202297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
202397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    return mOMX->setParameter(
202497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
202597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
202697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
202797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
202897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu}
202997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
20308a4728966dc9c78e21c3c93a927707e93c05e5e0Rachadstatus_t ACodec::setupEAC3Codec(
20318a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        bool encoder, int32_t numChannels, int32_t sampleRate) {
20328a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    status_t err = setupRawAudioFormat(
20338a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
20348a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
20358a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (err != OK) {
20368a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return err;
20378a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
20388a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
20398a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (encoder) {
20408a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        ALOGW("EAC3 encoding is not supported.");
20418a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return INVALID_OPERATION;
20428a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
20438a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
20448a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    OMX_AUDIO_PARAM_ANDROID_EAC3TYPE def;
20458a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    InitOMXParams(&def);
20468a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nPortIndex = kPortIndexInput;
20478a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
20488a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    err = mOMX->getParameter(
20498a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            mNode,
20508a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
20518a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            &def,
20528a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            sizeof(def));
20538a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
20548a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (err != OK) {
20558a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return err;
20568a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
20578a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
20588a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nChannels = numChannels;
20598a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nSampleRate = sampleRate;
20608a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
20618a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    return mOMX->setParameter(
20628a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            mNode,
20638a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
20648a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            &def,
20658a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            sizeof(def));
20668a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad}
20678a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
20685778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
20695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        bool isAMRWB, int32_t bps) {
20705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (isAMRWB) {
20715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 6600) {
20725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB0;
20735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 8850) {
20745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB1;
20755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 12650) {
20765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB2;
20775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 14250) {
20785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB3;
20795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 15850) {
20805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB4;
20815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 18250) {
20825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB5;
20835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 19850) {
20845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB6;
20855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 23050) {
20865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB7;
20875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 23850 bps
20905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeWB8;
20915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {  // AMRNB
20925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 4750) {
20935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB0;
20945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5150) {
20955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB1;
20965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5900) {
20975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB2;
20985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 6700) {
20995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB3;
21005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7400) {
21015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB4;
21025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7950) {
21035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB5;
21045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 10200) {
21055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB6;
21065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 12200 bps
21095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeNB7;
21105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
21135778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
2114729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_AMRTYPE def;
2115729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
21165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
2117729de186450f78c099637e1fce743fe531862c52Andreas Huber
2118729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err =
2119729de186450f78c099637e1fce743fe531862c52Andreas Huber        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
2120729de186450f78c099637e1fce743fe531862c52Andreas Huber
2121729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2122729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2123729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2124729de186450f78c099637e1fce743fe531862c52Andreas Huber
2125729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
21265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
21275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
21295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
2130729de186450f78c099637e1fce743fe531862c52Andreas Huber
21315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2134729de186450f78c099637e1fce743fe531862c52Andreas Huber
21355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupRawAudioFormat(
21365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
21375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            isWAMR ? 16000 : 8000 /* sampleRate */,
21385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            1 /* numChannels */);
2139729de186450f78c099637e1fce743fe531862c52Andreas Huber}
2140729de186450f78c099637e1fce743fe531862c52Andreas Huber
214117c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissenstatus_t ACodec::setupG711Codec(bool encoder, int32_t sampleRate, int32_t numChannels) {
21425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(!encoder);  // XXX TODO
21435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2144729de186450f78c099637e1fce743fe531862c52Andreas Huber    return setupRawAudioFormat(
214517c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            kPortIndexInput, sampleRate, numChannels);
2146729de186450f78c099637e1fce743fe531862c52Andreas Huber}
2147729de186450f78c099637e1fce743fe531862c52Andreas Huber
21482f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivistatus_t ACodec::setupFlacCodec(
21492f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
21502f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
21512f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder) {
21522f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        OMX_AUDIO_PARAM_FLACTYPE def;
21532f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        InitOMXParams(&def);
21542f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nPortIndex = kPortIndexOutput;
21552f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
21562f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        // configure compression level
21572f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        status_t err = mOMX->getParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
21582f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
21592f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
21602f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
21612f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
21622f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nCompressionLevel = compressionLevel;
21632f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        err = mOMX->setParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
21642f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
21652f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
21662f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
21672f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
21682f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
21692f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
21702f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    return setupRawAudioFormat(
21712f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            encoder ? kPortIndexInput : kPortIndexOutput,
21722f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            sampleRate,
21732f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            numChannels);
21742f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi}
21752f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
2176729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t ACodec::setupRawAudioFormat(
2177729de186450f78c099637e1fce743fe531862c52Andreas Huber        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
2178729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
2179729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
2180729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.nPortIndex = portIndex;
2181729de186450f78c099637e1fce743fe531862c52Andreas Huber
2182729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err = mOMX->getParameter(
2183729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2184729de186450f78c099637e1fce743fe531862c52Andreas Huber
2185729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2186729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2187729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2188729de186450f78c099637e1fce743fe531862c52Andreas Huber
2189729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
2190729de186450f78c099637e1fce743fe531862c52Andreas Huber
2191729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->setParameter(
2192729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2193729de186450f78c099637e1fce743fe531862c52Andreas Huber
2194729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2195729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2196729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2197729de186450f78c099637e1fce743fe531862c52Andreas Huber
2198729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
2199729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&pcmParams);
2200729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nPortIndex = portIndex;
2201729de186450f78c099637e1fce743fe531862c52Andreas Huber
2202729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->getParameter(
2203729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
2204729de186450f78c099637e1fce743fe531862c52Andreas Huber
2205729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2206729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2207729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2208729de186450f78c099637e1fce743fe531862c52Andreas Huber
2209729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nChannels = numChannels;
2210729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.eNumData = OMX_NumericalDataSigned;
2211729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.bInterleaved = OMX_TRUE;
2212729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nBitPerSample = 16;
2213729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nSamplingRate = sampleRate;
2214729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
2215729de186450f78c099637e1fce743fe531862c52Andreas Huber
2216c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber    if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
2217c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber        return OMX_ErrorNone;
2218729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2219729de186450f78c099637e1fce743fe531862c52Andreas Huber
2220729de186450f78c099637e1fce743fe531862c52Andreas Huber    return mOMX->setParameter(
2221729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
2222729de186450f78c099637e1fce743fe531862c52Andreas Huber}
2223729de186450f78c099637e1fce743fe531862c52Andreas Huber
22245a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachadstatus_t ACodec::configureTunneledVideoPlayback(
222597827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad        int32_t audioHwSync, const sp<ANativeWindow> &nativeWindow) {
22265a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    native_handle_t* sidebandHandle;
22275a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
22285a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    status_t err = mOMX->configureVideoTunnelMode(
22295a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            mNode, kPortIndexOutput, OMX_TRUE, audioHwSync, &sidebandHandle);
22305a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    if (err != OK) {
22315a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        ALOGE("configureVideoTunnelMode failed! (err %d).", err);
22325a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        return err;
22335a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    }
22345a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
22355a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    err = native_window_set_sideband_stream(nativeWindow.get(), sidebandHandle);
22365a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    if (err != OK) {
22375a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        ALOGE("native_window_set_sideband_stream(%p) failed! (err %d).",
22385a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                sidebandHandle, err);
22395a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        return err;
22405a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    }
22415a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
22425a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    return OK;
22435a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad}
22445a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
2245f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoPortFormatType(
2246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
2247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_VIDEO_CODINGTYPE compressionFormat,
22480d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        OMX_COLOR_FORMATTYPE colorFormat,
22490d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        bool usingNativeBuffers) {
2250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
2251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
2252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = portIndex;
2253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
2254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool found = false;
2255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 index = 0;
2257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (;;) {
2258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        format.nIndex = index;
2259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->getParameter(
2260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamVideoPortFormat,
2261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &format, sizeof(format));
2262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
2264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return err;
2265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2267229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        // substitute back flexible color format to codec supported format
2268229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        OMX_U32 flexibleEquivalent;
22690d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (compressionFormat == OMX_VIDEO_CodingUnused
22700d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && isFlexibleColorFormat(
22710d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        mOMX, mNode, format.eColorFormat, usingNativeBuffers, &flexibleEquivalent)
22720d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && colorFormat == flexibleEquivalent) {
2273229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            ALOGI("[%s] using color format %#x in place of %#x",
2274229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                    mComponentName.c_str(), format.eColorFormat, colorFormat);
2275229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            colorFormat = format.eColorFormat;
2276229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
2277229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
2278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The following assertion is violated by TI's video decoder.
2279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // CHECK_EQ(format.nIndex, index);
2280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
2282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexInput
2283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && colorFormat == format.eColorFormat) {
2284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eCompressionFormat does not seem right.
2285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
2286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
2287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexOutput
2289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && compressionFormat == format.eCompressionFormat) {
2290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eColorFormat does not seem right.
2291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
2292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
2293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (format.eCompressionFormat == compressionFormat
2297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && format.eColorFormat == colorFormat) {
2298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            found = true;
2299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ++index;
2303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!found) {
2306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return UNKNOWN_ERROR;
2307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->setParameter(
2310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
2311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
2312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
2314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
23160d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// Set optimal output format. OMX component lists output formats in the order
23170d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// of preference, but this got more complicated since the introduction of flexible
23180d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// YUV formats. We support a legacy behavior for applications that do not use
23190d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// surface output, do not specify an output format, but expect a "usable" standard
23200d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// OMX format. SW readable and standard formats must be flex-YUV.
23210d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar//
23220d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// Suggested preference order:
23230d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal format for texture rendering (mediaplayer behavior)
23240d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal SW readable & texture renderable format (flex-YUV support)
23250d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal SW readable non-renderable format (flex-YUV bytebuffer support)
23260d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - legacy "usable" standard formats
23270d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar//
23280d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// For legacy support, we prefer a standard format, but will settle for a SW readable
23290d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// flex-YUV format.
23300d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnarstatus_t ACodec::setSupportedOutputFormat(bool getLegacyFlexibleFormat) {
23310d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    OMX_VIDEO_PARAM_PORTFORMATTYPE format, legacyFormat;
2332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
2333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = kPortIndexOutput;
2334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
23350d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    InitOMXParams(&legacyFormat);
23360d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    // this field will change when we find a suitable legacy format
23370d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    legacyFormat.eColorFormat = OMX_COLOR_FormatUnused;
2338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
23390d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    for (OMX_U32 index = 0; ; ++index) {
23400d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        format.nIndex = index;
23410d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        status_t err = mOMX->getParameter(
23420d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                mNode, OMX_IndexParamVideoPortFormat,
23430d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                &format, sizeof(format));
23440d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (err != OK) {
23450d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            // no more formats, pick legacy format if found
23460d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            if (legacyFormat.eColorFormat != OMX_COLOR_FormatUnused) {
23470d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                 memcpy(&format, &legacyFormat, sizeof(format));
23480d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                 break;
23490d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            }
23500d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            return err;
23510d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
23520d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (format.eCompressionFormat != OMX_VIDEO_CodingUnused) {
23530d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            return OMX_ErrorBadParameter;
23540d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
23550d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (!getLegacyFlexibleFormat) {
23560d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            break;
23570d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
23580d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        // standard formats that were exposed to users before
23590d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (format.eColorFormat == OMX_COLOR_FormatYUV420Planar
23600d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_COLOR_FormatYUV420PackedPlanar
23610d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar
23620d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_COLOR_FormatYUV420PackedSemiPlanar
23630d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar) {
23640d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            break;
23650d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
23660d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        // find best legacy non-standard format
23670d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        OMX_U32 flexibleEquivalent;
23680d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (legacyFormat.eColorFormat == OMX_COLOR_FormatUnused
23690d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && isFlexibleColorFormat(
23700d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        mOMX, mNode, format.eColorFormat, false /* usingNativeBuffers */,
23710d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        &flexibleEquivalent)
23720d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && flexibleEquivalent == OMX_COLOR_FormatYUV420Flexible) {
23730d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            memcpy(&legacyFormat, &format, sizeof(format));
23740d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
23750d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    }
2376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mOMX->setParameter(
2377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
2378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
2379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2381e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic const struct VideoCodingMapEntry {
2382e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    const char *mMime;
2383e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    OMX_VIDEO_CODINGTYPE mVideoCodingType;
2384e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber} kVideoCodingMapEntry[] = {
2385e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC },
23862472b1c0d63454e5d90a982bd6c555de6c3127bdRachad    { MEDIA_MIMETYPE_VIDEO_HEVC, OMX_VIDEO_CodingHEVC },
2387e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 },
2388e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 },
2389e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 },
239094705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 },
239194705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 },
2392e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber};
2393e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
23945778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic status_t GetVideoCodingTypeFromMime(
23955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
2396e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
2397e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
2398e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
2399e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) {
2400e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *codingType = kVideoCodingMapEntry[i].mVideoCodingType;
2401e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
2402e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
2403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2405e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    *codingType = OMX_VIDEO_CodingUnused;
2406e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2407e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
2408e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
2409e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2410e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic status_t GetMimeTypeForVideoCoding(
2411e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        OMX_VIDEO_CODINGTYPE codingType, AString *mime) {
2412e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
2413e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
2414e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
2415e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) {
2416e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *mime = kVideoCodingMapEntry[i].mMime;
2417e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
2418e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
2419e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
2420e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2421e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    mime->clear();
2422e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2423e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
24245778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
24255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24265778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoDecoder(
24270d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        const char *mime, const sp<AMessage> &msg, bool haveNativeWindow) {
242889869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    int32_t width, height;
242989869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    if (!msg->findInt32("width", &width)
243089869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            || !msg->findInt32("height", &height)) {
243189869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        return INVALID_OPERATION;
243289869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    }
243389869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar
24345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
24355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
24365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
24385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
24395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
2442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
2443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
244889869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    int32_t tmp;
244989869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    if (msg->findInt32("color-format", &tmp)) {
245089869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        OMX_COLOR_FORMATTYPE colorFormat =
245189869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            static_cast<OMX_COLOR_FORMATTYPE>(tmp);
245289869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        err = setVideoPortFormatType(
24530d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                kPortIndexOutput, OMX_VIDEO_CodingUnused, colorFormat, haveNativeWindow);
245489869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        if (err != OK) {
245589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            ALOGW("[%s] does not support color format %d",
245689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar                  mComponentName.c_str(), colorFormat);
24570d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            err = setSupportedOutputFormat(!haveNativeWindow /* getLegacyFlexibleFormat */);
245889869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        }
245989869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    } else {
24600d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        err = setSupportedOutputFormat(!haveNativeWindow /* getLegacyFlexibleFormat */);
246189869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    }
2462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
246778b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    int32_t frameRateInt;
246878b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    float frameRateFloat;
246978b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    if (!msg->findFloat("frame-rate", &frameRateFloat)) {
247078b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        if (!msg->findInt32("frame-rate", &frameRateInt)) {
247178b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            frameRateInt = -1;
247278b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        }
247378b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        frameRateFloat = (float)frameRateInt;
247478b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    }
247578b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad
2476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
247778b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            kPortIndexInput, width, height, compressionFormat, frameRateFloat);
2478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
2484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
2485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
24935778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) {
24945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
24955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("color-format", &tmp)) {
24965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
24975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_COLOR_FORMATTYPE colorFormat =
25005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        static_cast<OMX_COLOR_FORMATTYPE>(tmp);
25015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setVideoPortFormatType(
25035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
25045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
25065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support color format %d",
25075778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str(), colorFormat);
25085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
25105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Input port configuration */
25135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
25155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&def);
25165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
25185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexInput;
25205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
25225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
25235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
25255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
25265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t width, height, bitrate;
25295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("width", &width)
25305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("height", &height)
25315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("bitrate", &bitrate)) {
25325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
25335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
25365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
25375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t stride;
25395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("stride", &stride)) {
25405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        stride = width;
25415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nStride = stride;
25445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t sliceHeight;
25465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("slice-height", &sliceHeight)) {
25475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sliceHeight = height;
25485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nSliceHeight = sliceHeight;
25515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
25535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
25555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
25565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
25575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
25585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
25595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
25605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
25612c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        mTimePerFrameUs = (int64_t) (1000000.0f / frameRate);
25625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
25655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
2566a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    // this is redundant as it was already set up in setVideoPortFormatType
2567a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    // FIXME for now skip this only for flexible YUV formats
2568a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    if (colorFormat != OMX_COLOR_FormatYUV420Flexible) {
2569a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar        video_def->eColorFormat = colorFormat;
2570a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    }
25715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
25735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
25745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
25765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set input port definition parameters.",
25775778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
25785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
25805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Output port configuration */
25835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
25855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
25865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
25885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
25895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
25925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
25935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
25955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support compression format %d",
25965778822d86b0337407514b9372562b86edfa91cdAndreas Huber             mComponentName.c_str(), compressionFormat);
25975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
25995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexOutput;
26025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
26045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
26055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
26075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
26085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
26115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
26125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = 0;
26135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nBitrate = bitrate;
26145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = compressionFormat;
26155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = OMX_COLOR_FormatUnused;
26165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
26185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
26195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
26215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set output port definition parameters.",
26225778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
26235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
26255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (compressionFormat) {
26285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingMPEG4:
26295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupMPEG4EncoderParameters(msg);
26305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
26315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingH263:
26335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupH263EncoderParameters(msg);
26345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
26355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingAVC:
26375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupAVCEncoderParameters(msg);
26385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
26395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2640c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        case OMX_VIDEO_CodingHEVC:
2641c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            err = setupHEVCEncoderParameters(msg);
2642c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            break;
2643c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
264489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP8:
264589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP9:
264689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            err = setupVPXEncoderParameters(msg);
264789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            break;
264889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
26495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
26505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
26515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGI("setupVideoEncoder succeeded");
26545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
26565778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
26575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26580dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dongstatus_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) {
26590dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    OMX_VIDEO_PARAM_INTRAREFRESHTYPE params;
26600dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    InitOMXParams(&params);
26610dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.nPortIndex = kPortIndexOutput;
26620dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
26630dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode);
26640dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
26650dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic ||
26660dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
26670dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
26680dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) {
26690dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
26700dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
26710dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nCirMBs = mbs;
26720dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
26730dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
26740dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive ||
26750dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
26760dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
26770dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) {
26780dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
26790dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
26800dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirMBs = mbs;
26810dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
26820dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t ref;
26830dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) {
26840dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
26850dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
26860dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirRef = ref;
26870dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
26880dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
26890dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = mOMX->setParameter(
26900dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            mNode, OMX_IndexParamVideoIntraRefresh,
26910dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            &params, sizeof(params));
26920dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    return err;
26930dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong}
26940dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
26955778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
26965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (iFramesInterval < 0) {
26975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0xFFFFFFFF;
26985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (iFramesInterval == 0) {
26995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0;
27005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_U32 ret = frameRate * iFramesInterval;
27025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return ret;
27035778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
27045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
270596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatic OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) {
270696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    int32_t tmp;
270796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    if (!msg->findInt32("bitrate-mode", &tmp)) {
270896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        return OMX_Video_ControlRateVariable;
270996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    }
271096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
271196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp);
271296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber}
271396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
27145778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
27155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
27165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
27175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
27185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
27195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
272196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
272296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
27235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
27245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
27255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
27265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
27275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
27285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
27295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
27305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
27335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&mpeg4type);
27345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPortIndex = kPortIndexOutput;
27355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
27375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
27385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
27405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
27415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nSliceHeaderSpacing = 0;
27445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bSVH = OMX_FALSE;
27455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bGov = OMX_FALSE;
27465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nAllowedPictureTypes =
27485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
27495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
27515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mpeg4type.nPFrames == 0) {
27525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
27535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nBFrames = 0;
27555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nIDCVLCThreshold = 0;
27565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bACPred = OMX_TRUE;
27575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nMaxPacketSize = 256;
27585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nTimeIncRes = 1000;
27595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nHeaderExtension = 0;
27605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bReversibleVLC = OMX_FALSE;
27615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
27635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
27645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
27655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
27665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
27675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
27685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
27705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
27725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
27735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
27745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
27765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
27775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
27805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
27815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
27835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
27845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
278696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
27875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
27895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
27905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
27935778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
27945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27955778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
27965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
27975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
27985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
27995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
28005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
280296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
280396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
28045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
28055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
28065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
28075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
28085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
28095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
28105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
28115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_H263TYPE h263type;
28145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h263type);
28155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPortIndex = kPortIndexOutput;
28165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
28185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
28195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
28215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
28225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nAllowedPictureTypes =
28255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
28265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
28285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h263type.nPFrames == 0) {
28295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
28305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nBFrames = 0;
28325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
28345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
28355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
28365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
28375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
28385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
28395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
28415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
28435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
28445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
28455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
28475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
28485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bPLUSPTYPEAllowed = OMX_FALSE;
28515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bForceRoundingTypeToZero = OMX_FALSE;
28525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPictureHeaderRepetition = 0;
28535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nGOBHeaderInterval = 0;
28545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
28565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
28575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
28595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
28605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
286296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
28635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
28655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
28665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
28695778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
28705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2871a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar// static
2872a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnarint /* OMX_VIDEO_AVCLEVELTYPE */ ACodec::getAVCLevelFor(
2873a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        int width, int height, int rate, int bitrate,
2874a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        OMX_VIDEO_AVCPROFILETYPE profile) {
2875a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    // convert bitrate to main/baseline profile kbps equivalent
2876a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    switch (profile) {
2877a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        case OMX_VIDEO_AVCProfileHigh10:
2878a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 3000); break;
2879a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        case OMX_VIDEO_AVCProfileHigh:
2880a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 1250); break;
2881a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        default:
2882a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 1000); break;
2883a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    }
2884a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
2885a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    // convert size and rate to MBs
2886a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    width = divUp(width, 16);
2887a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    height = divUp(height, 16);
2888a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    int mbs = width * height;
2889a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    rate *= mbs;
2890a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    int maxDimension = max(width, height);
2891a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
2892a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    static const int limits[][5] = {
2893a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        /*   MBps     MB   dim  bitrate        level */
2894a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    1485,    99,  28,     64, OMX_VIDEO_AVCLevel1  },
2895a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    1485,    99,  28,    128, OMX_VIDEO_AVCLevel1b },
2896a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    3000,   396,  56,    192, OMX_VIDEO_AVCLevel11 },
2897a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    6000,   396,  56,    384, OMX_VIDEO_AVCLevel12 },
2898a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   11880,   396,  56,    768, OMX_VIDEO_AVCLevel13 },
2899a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   11880,   396,  56,   2000, OMX_VIDEO_AVCLevel2  },
2900a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   19800,   792,  79,   4000, OMX_VIDEO_AVCLevel21 },
2901a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   20250,  1620, 113,   4000, OMX_VIDEO_AVCLevel22 },
2902a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   40500,  1620, 113,  10000, OMX_VIDEO_AVCLevel3  },
2903a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  108000,  3600, 169,  14000, OMX_VIDEO_AVCLevel31 },
2904a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  216000,  5120, 202,  20000, OMX_VIDEO_AVCLevel32 },
2905a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  245760,  8192, 256,  20000, OMX_VIDEO_AVCLevel4  },
2906a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  245760,  8192, 256,  50000, OMX_VIDEO_AVCLevel41 },
2907a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  522240,  8704, 263,  50000, OMX_VIDEO_AVCLevel42 },
2908a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  589824, 22080, 420, 135000, OMX_VIDEO_AVCLevel5  },
2909a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  983040, 36864, 543, 240000, OMX_VIDEO_AVCLevel51 },
2910a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        { 2073600, 36864, 543, 240000, OMX_VIDEO_AVCLevel52 },
2911a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    };
2912a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
2913a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    for (size_t i = 0; i < ARRAY_SIZE(limits); i++) {
2914a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        const int (&limit)[5] = limits[i];
2915a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        if (rate <= limit[0] && mbs <= limit[1] && maxDimension <= limit[2]
2916a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar                && bitrate <= limit[3]) {
2917a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            return limit[4];
2918a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        }
2919a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    }
2920a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    return 0;
2921a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar}
2922a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
29235778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
29245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
29255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
29265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
29275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
29285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
293096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
293196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
29325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
29335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
29345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
29355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
29365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
29375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
29385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
29395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29410dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = OK;
29420dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    int32_t intraRefreshMode = 0;
29430dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) {
29440dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode);
29450dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (err != OK) {
29460dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
29470dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong                    err, intraRefreshMode);
29480dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return err;
29490dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
29500dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
29510dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
29525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_AVCTYPE h264type;
29535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h264type);
29545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nPortIndex = kPortIndexOutput;
29555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29560dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    err = mOMX->getParameter(
29575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
29585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
29605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
29615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nAllowedPictureTypes =
29645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
29655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
29675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
29685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
29695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
29705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
29715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
29725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
29745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
29765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
29775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
29785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
29805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
29815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // XXX
29847c25df82dfc8bbedb58608242f0d923a4594bb14James Dong    if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) {
29857c25df82dfc8bbedb58608242f0d923a4594bb14James Dong        ALOGW("Use baseline profile instead of %d for AVC recording",
29867c25df82dfc8bbedb58608242f0d923a4594bb14James Dong            h264type.eProfile);
29875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
29885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
29915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nSliceHeaderSpacing = 0;
29925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bUseHadamard = OMX_TRUE;
29935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefFrames = 1;
29945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nBFrames = 0;
29955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
29965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (h264type.nPFrames == 0) {
29975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
29985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
29995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx10ActiveMinus1 = 0;
30005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx11ActiveMinus1 = 0;
30015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bEntropyCodingCABAC = OMX_FALSE;
30025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bWeightedPPrediction = OMX_FALSE;
30035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bconstIpred = OMX_FALSE;
30045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirect8x8Inference = OMX_FALSE;
30055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirectSpatialTemporal = OMX_FALSE;
30065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nCabacInitIdc = 0;
30075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
30085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.nBFrames != 0) {
30105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
30115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
30125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableUEP = OMX_FALSE;
30145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableFMO = OMX_FALSE;
30155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableASO = OMX_FALSE;
30165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableRS = OMX_FALSE;
30175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bFrameMBsOnly = OMX_TRUE;
30185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bMBAFF = OMX_FALSE;
30195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
30205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
30225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
30235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
30255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
30265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
30275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
302896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return configureBitrate(bitrate, bitrateMode);
30295778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
30305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3031c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachadstatus_t ACodec::setupHEVCEncoderParameters(const sp<AMessage> &msg) {
3032c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    int32_t bitrate, iFrameInterval;
3033c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findInt32("bitrate", &bitrate)
3034c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
3035c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return INVALID_OPERATION;
3036c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
3037c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3038c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
3039c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3040c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    float frameRate;
3041c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findFloat("frame-rate", &frameRate)) {
3042c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t tmp;
3043c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("frame-rate", &tmp)) {
3044c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
3045c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
3046c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        frameRate = (float)tmp;
3047c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
3048c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3049c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_PARAM_HEVCTYPE hevcType;
3050c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    InitOMXParams(&hevcType);
3051c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    hevcType.nPortIndex = kPortIndexOutput;
3052c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3053c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    status_t err = OK;
3054c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    err = mOMX->getParameter(
3055c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
3056c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
3057c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
3058c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
3059c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3060c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    int32_t profile;
3061c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (msg->findInt32("profile", &profile)) {
3062c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t level;
3063c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("level", &level)) {
3064c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
3065c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
3066c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3067c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        err = verifySupportForProfileAndLevel(profile, level);
3068c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (err != OK) {
3069c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return err;
3070c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
3071c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3072c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eProfile = static_cast<OMX_VIDEO_HEVCPROFILETYPE>(profile);
3073c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eLevel = static_cast<OMX_VIDEO_HEVCLEVELTYPE>(level);
3074c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
3075c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3076c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    // TODO: Need OMX structure definition for setting iFrameInterval
3077c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3078c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    err = mOMX->setParameter(
3079c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
3080c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
3081c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
3082c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
3083c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3084c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    return configureBitrate(bitrate, bitrateMode);
3085c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad}
3086c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
308789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huberstatus_t ACodec::setupVPXEncoderParameters(const sp<AMessage> &msg) {
308889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    int32_t bitrate;
30894154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    int32_t iFrameInterval = 0;
30904154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    size_t tsLayers = 0;
30914154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE pattern =
30924154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        OMX_VIDEO_VPXTemporalLayerPatternNone;
30934154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    static const uint32_t kVp8LayerRateAlloction
30944154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS]
30954154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS] = {
30964154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        {100, 100, 100},  // 1 layer
30974154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 60, 100, 100},  // 2 layers {60%, 40%}
30984154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 40,  60, 100},  // 3 layers {40%, 20%, 40%}
30994154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    };
310089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    if (!msg->findInt32("bitrate", &bitrate)) {
310189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        return INVALID_OPERATION;
310289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    }
31034154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    msg->findInt32("i-frame-interval", &iFrameInterval);
310489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
310589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
310689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
31074154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    float frameRate;
31084154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (!msg->findFloat("frame-rate", &frameRate)) {
31094154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        int32_t tmp;
31104154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (!msg->findInt32("frame-rate", &tmp)) {
31114154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            return INVALID_OPERATION;
31124154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
31134154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        frameRate = (float)tmp;
31144154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
31154154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
31164154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    AString tsSchema;
31174154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (msg->findString("ts-schema", &tsSchema)) {
31184154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (tsSchema == "webrtc.vp8.1-layer") {
31194154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
31204154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 1;
31214154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else if (tsSchema == "webrtc.vp8.2-layer") {
31224154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
31234154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 2;
31244154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else if (tsSchema == "webrtc.vp8.3-layer") {
31254154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
31264154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 3;
31274154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else {
31284154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            ALOGW("Unsupported ts-schema [%s]", tsSchema.c_str());
31294154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
31304154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
31314154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
31324154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
31334154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    InitOMXParams(&vp8type);
31344154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    vp8type.nPortIndex = kPortIndexOutput;
31354154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    status_t err = mOMX->getParameter(
31364154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
31374154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            &vp8type, sizeof(vp8type));
31384154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
31394154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (err == OK) {
31404154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (iFrameInterval > 0) {
31414154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nKeyFrameInterval = setPFramesSpacing(iFrameInterval, frameRate);
31424154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
31434154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.eTemporalPattern = pattern;
31444154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.nTemporalLayerCount = tsLayers;
31454154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (tsLayers > 0) {
31464154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            for (size_t i = 0; i < OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS; i++) {
31474154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                vp8type.nTemporalLayerBitrateRatio[i] =
31484154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                    kVp8LayerRateAlloction[tsLayers - 1][i];
31494154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            }
31504154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
31514154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (bitrateMode == OMX_Video_ControlRateConstant) {
31524154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMinQuantizer = 2;
31534154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMaxQuantizer = 63;
31544154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
31554154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
31564154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        err = mOMX->setParameter(
31574154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
31584154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                &vp8type, sizeof(vp8type));
31594154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (err != OK) {
31604154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            ALOGW("Extended VP8 parameters set failed: %d", err);
31614154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
31624154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
31634154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
316489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    return configureBitrate(bitrate, bitrateMode);
316589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber}
316689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
31675778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::verifySupportForProfileAndLevel(
31685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t profile, int32_t level) {
31695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
31705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&params);
31715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    params.nPortIndex = kPortIndexOutput;
31725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (params.nProfileIndex = 0;; ++params.nProfileIndex) {
31745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
31755778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode,
31765778822d86b0337407514b9372562b86edfa91cdAndreas Huber                OMX_IndexParamVideoProfileLevelQuerySupported,
31775778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &params,
31785778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sizeof(params));
31795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
31815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
31825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
31835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
31855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
31865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (profile == supportedProfile && level <= supportedLevel) {
31885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OK;
31895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
31905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
31915778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
31925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
319396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatus_t ACodec::configureBitrate(
319496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) {
31955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
31965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&bitrateType);
31975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
31985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
32005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
32015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
32025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
32045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
32055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
32065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
320796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    bitrateType.eControlRate = bitrateMode;
32085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nTargetBitrate = bitrate;
32095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
32115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
32125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
32135778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
32145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32155778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupErrorCorrectionParameters() {
32165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
32175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&errorCorrectionType);
32185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nPortIndex = kPortIndexOutput;
32195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
32215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
32225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
32235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
32255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OK;  // Optional feature. Ignore this failure
32265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
32275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableHEC = OMX_FALSE;
32295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableResync = OMX_TRUE;
32305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nResynchMarkerSpacing = 256;
32315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
32325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableRVLC = OMX_FALSE;
32335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
32355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
32365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
32375778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
32385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3239f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoFormatOnPort(
3240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
324178b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat,
324278b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        float frameRate) {
3243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
3244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
3245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
3246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
3248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
3250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
3251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
3253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
3255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // XXX Need a (much) better heuristic to compute input buffer sizes.
3256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const size_t X = 64 * 1024;
3257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (def.nBufferSize < X) {
3258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.nBufferSize = X;
3259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
3263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameWidth = width;
3265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameHeight = height;
3266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
3268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eCompressionFormat = compressionFormat;
3269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eColorFormat = OMX_COLOR_FormatUnused;
327078b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        if (frameRate >= 0) {
327178b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
327278b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        }
3273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
3276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
3277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
3279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3281f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::initNativeWindow() {
3282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL) {
3283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
3284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
3287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
3288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3290d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Hubersize_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
3291d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    size_t n = 0;
3292d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
3293d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
3294d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        const BufferInfo &info = mBuffers[portIndex].itemAt(i);
3295d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
3296d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
3297d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            ++n;
3298d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        }
3299d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    }
3300d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
3301d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    return n;
3302d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber}
3303d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
33047e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubersize_t ACodec::countBuffersOwnedByNativeWindow() const {
33057e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    size_t n = 0;
33067e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
33077e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
33087e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
33097e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
33107e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
33117e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            ++n;
33127e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        }
33137e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
33147e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
33157e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    return n;
33167e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
33177e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
33187e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubervoid ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
33197e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (mNativeWindow == NULL) {
33207e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        return;
33217e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
33227e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
3323e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    while (countBuffersOwnedByNativeWindow() > mNumUndequeuedBuffers
33247e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            && dequeueBufferFromNativeWindow() != NULL) {
3325c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        // these buffers will be submitted as regular buffers; account for this
3326c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        if (mStoreMetaDataInOutputBuffers && mMetaDataBuffersToSubmit > 0) {
3327c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar            --mMetaDataBuffersToSubmit;
3328c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        }
33297e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
33307e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
33317e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
3332f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs(
3333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
3334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
3335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
3336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus != BufferInfo::OWNED_BY_US
3338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3339609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGV("[%s] Buffer %u on port %u still has status %d",
3340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mComponentName.c_str(),
3341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info->mBufferID, portIndex, info->mStatus);
3342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
3343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3349f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs() {
3350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return allYourBuffersAreBelongToUs(kPortIndexInput)
3351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        && allYourBuffersAreBelongToUs(kPortIndexOutput);
3352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3354f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::deferMessage(const sp<AMessage> &msg) {
3355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.push_back(msg);
3356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3358f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::processDeferredMessages() {
3359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> > queue = mDeferredQueue;
3360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.clear();
3361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> >::iterator it = queue.begin();
3363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while (it != queue.end()) {
3364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        onMessageReceived(*it++);
3365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
336803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar// static
3369229d242665c612fd97431d1e7ac004823b47f181Lajos Molnarbool ACodec::describeDefaultColorFormat(DescribeColorFormatParams &params) {
337003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    MediaImage &image = params.sMediaImage;
337103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    memset(&image, 0, sizeof(image));
337203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
337303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mType = MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
337403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mNumPlanes = 0;
337503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
337603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    const OMX_COLOR_FORMATTYPE fmt = params.eColorFormat;
337703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mWidth = params.nFrameWidth;
337803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mHeight = params.nFrameHeight;
337903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
338003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    // only supporting YUV420
338103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    if (fmt != OMX_COLOR_FormatYUV420Planar &&
338203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        fmt != OMX_COLOR_FormatYUV420PackedPlanar &&
338303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        fmt != OMX_COLOR_FormatYUV420SemiPlanar &&
33845a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        fmt != OMX_COLOR_FormatYUV420PackedSemiPlanar &&
33855a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        fmt != HAL_PIXEL_FORMAT_YV12) {
338603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        ALOGW("do not know color format 0x%x = %d", fmt, fmt);
3387229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return false;
338803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    }
338903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
3390b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    // TEMPORARY FIX for some vendors that advertise sliceHeight as 0
3391b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    if (params.nStride != 0 && params.nSliceHeight == 0) {
3392b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        ALOGW("using sliceHeight=%u instead of what codec advertised (=0)",
3393b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar                params.nFrameHeight);
3394b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        params.nSliceHeight = params.nFrameHeight;
3395b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    }
3396b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar
3397b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    // we need stride and slice-height to be non-zero
3398b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    if (params.nStride == 0 || params.nSliceHeight == 0) {
3399b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        ALOGW("cannot describe color format 0x%x = %d with stride=%u and sliceHeight=%u",
3400b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar                fmt, fmt, params.nStride, params.nSliceHeight);
3401b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        return false;
3402b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    }
3403b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar
340403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    // set-up YUV format
340503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mType = MediaImage::MEDIA_IMAGE_TYPE_YUV;
340603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mNumPlanes = 3;
340703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mBitDepth = 8;
340803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mOffset = 0;
340903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mColInc = 1;
341003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mRowInc = params.nStride;
341103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mHorizSubsampling = 1;
341203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mVertSubsampling = 1;
341303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
34145a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar    switch ((int)fmt) {
34155a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        case HAL_PIXEL_FORMAT_YV12:
34165a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            if (params.bUsingNativeBuffers) {
34175a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                size_t ystride = align(params.nStride, 16);
34185a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                size_t cstride = align(params.nStride / 2, 16);
34195a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.Y].mRowInc = ystride;
34205a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
34215a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mOffset = ystride * params.nSliceHeight;
34225a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mColInc = 1;
34235a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mRowInc = cstride;
34245a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mHorizSubsampling = 2;
34255a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mVertSubsampling = 2;
34265a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
34275a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mOffset = image.mPlane[image.V].mOffset
34285a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                        + (cstride * params.nSliceHeight / 2);
34295a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mColInc = 1;
34305a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mRowInc = cstride;
34315a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mHorizSubsampling = 2;
34325a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mVertSubsampling = 2;
34335a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                break;
34345a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            } else {
34355a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                // fall through as YV12 is used for YUV420Planar by some codecs
34365a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            }
34375a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
34385a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        case OMX_COLOR_FormatYUV420Planar:
343903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420PackedPlanar:
344003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight;
344103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mColInc = 1;
344203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mRowInc = params.nStride / 2;
344303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mHorizSubsampling = 2;
344403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mVertSubsampling = 2;
344503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
344603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset
344703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    + (params.nStride * params.nSliceHeight / 4);
344803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mColInc = 1;
344903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mRowInc = params.nStride / 2;
345003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mHorizSubsampling = 2;
345103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mVertSubsampling = 2;
345203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            break;
345303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
345403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420SemiPlanar:
345503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            // FIXME: NV21 for sw-encoder, NV12 for decoder and hw-encoder
345603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420PackedSemiPlanar:
345703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            // NV12
345803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight;
345903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mColInc = 2;
346003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mRowInc = params.nStride;
346103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mHorizSubsampling = 2;
346203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mVertSubsampling = 2;
346303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
346403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset + 1;
346503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mColInc = 2;
346603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mRowInc = params.nStride;
346703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mHorizSubsampling = 2;
346803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mVertSubsampling = 2;
346903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            break;
347003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
347103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        default:
347203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            TRESPASS();
347303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    }
3474229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    return true;
3475229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar}
3476229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3477229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar// static
3478229d242665c612fd97431d1e7ac004823b47f181Lajos Molnarbool ACodec::describeColorFormat(
3479229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        const sp<IOMX> &omx, IOMX::node_id node,
3480229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        DescribeColorFormatParams &describeParams)
3481229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar{
3482229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    OMX_INDEXTYPE describeColorFormatIndex;
3483229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    if (omx->getExtensionIndex(
3484229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            node, "OMX.google.android.index.describeColorFormat",
3485229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            &describeColorFormatIndex) != OK ||
3486229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        omx->getParameter(
3487229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            node, describeColorFormatIndex,
3488229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            &describeParams, sizeof(describeParams)) != OK) {
3489229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return describeDefaultColorFormat(describeParams);
3490229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    }
3491229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    return describeParams.sMediaImage.mType !=
3492229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
3493229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar}
3494229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3495229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar// static
3496229d242665c612fd97431d1e7ac004823b47f181Lajos Molnarbool ACodec::isFlexibleColorFormat(
3497229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar         const sp<IOMX> &omx, IOMX::node_id node,
34980d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar         uint32_t colorFormat, bool usingNativeBuffers, OMX_U32 *flexibleEquivalent) {
3499229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    DescribeColorFormatParams describeParams;
3500229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    InitOMXParams(&describeParams);
3501229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.eColorFormat = (OMX_COLOR_FORMATTYPE)colorFormat;
3502229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    // reasonable dummy values
3503229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nFrameWidth = 128;
3504229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nFrameHeight = 128;
3505229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nStride = 128;
3506229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nSliceHeight = 128;
35070d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    describeParams.bUsingNativeBuffers = (OMX_BOOL)usingNativeBuffers;
3508229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3509229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    CHECK(flexibleEquivalent != NULL);
3510229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3511229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    if (!describeColorFormat(omx, node, describeParams)) {
3512229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return false;
3513229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    }
3514229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3515229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    const MediaImage &img = describeParams.sMediaImage;
3516229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    if (img.mType == MediaImage::MEDIA_IMAGE_TYPE_YUV) {
3517229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        if (img.mNumPlanes != 3 ||
3518229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            img.mPlane[img.Y].mHorizSubsampling != 1 ||
3519229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            img.mPlane[img.Y].mVertSubsampling != 1) {
3520229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            return false;
3521229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
3522229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3523229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        // YUV 420
3524229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        if (img.mPlane[img.U].mHorizSubsampling == 2
3525229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.U].mVertSubsampling == 2
3526229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.V].mHorizSubsampling == 2
3527229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.V].mVertSubsampling == 2) {
3528229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            // possible flexible YUV420 format
3529229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            if (img.mBitDepth <= 8) {
3530229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar               *flexibleEquivalent = OMX_COLOR_FormatYUV420Flexible;
3531229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar               return true;
3532229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            }
3533229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
3534229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    }
3535229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    return false;
353603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar}
353703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
3538e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarstatus_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> &notify) {
3539e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    // TODO: catch errors an return them instead of using CHECK
354031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
354131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    InitOMXParams(&def);
3542e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    def.nPortIndex = portIndex;
354331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
354431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ(mOMX->getParameter(
354531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)),
354631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber             (status_t)OK);
354731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3548e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ((int)def.eDir,
3549e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            (int)(portIndex == kPortIndexOutput ? OMX_DirOutput : OMX_DirInput));
355031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
355131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    switch (def.eDomain) {
355231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainVideo:
355331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
355431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
3555e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            switch ((int)videoDef->eCompressionFormat) {
3556e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_VIDEO_CodingUnused:
3557e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3558e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(mIsEncoder ^ (portIndex == kPortIndexOutput));
3559e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
3560e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3561e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("stride", videoDef->nStride);
3562e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("slice-height", videoDef->nSliceHeight);
3563e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("color-format", videoDef->eColorFormat);
3564e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
35650d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                    if (mNativeWindow == NULL) {
35660d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        DescribeColorFormatParams describeParams;
35670d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        InitOMXParams(&describeParams);
35680d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.eColorFormat = videoDef->eColorFormat;
35690d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nFrameWidth = videoDef->nFrameWidth;
35700d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nFrameHeight = videoDef->nFrameHeight;
35710d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nStride = videoDef->nStride;
35720d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nSliceHeight = videoDef->nSliceHeight;
35730d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.bUsingNativeBuffers = OMX_FALSE;
35740d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar
35750d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        if (describeColorFormat(mOMX, mNode, describeParams)) {
35760d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                            notify->setBuffer(
35770d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                    "image-data",
35780d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                    ABuffer::CreateAsCopy(
35790d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                            &describeParams.sMediaImage,
35800d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                            sizeof(describeParams.sMediaImage)));
35815a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
35825a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                            MediaImage *img = &describeParams.sMediaImage;
35835a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                            ALOGV("[%s] MediaImage { F(%zux%zu) @%zu+%zu+%zu @%zu+%zu+%zu @%zu+%zu+%zu }",
35845a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                                    mComponentName.c_str(), img->mWidth, img->mHeight,
35855a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                                    img->mPlane[0].mOffset, img->mPlane[0].mColInc, img->mPlane[0].mRowInc,
35865a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                                    img->mPlane[1].mOffset, img->mPlane[1].mColInc, img->mPlane[1].mRowInc,
35875a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                                    img->mPlane[2].mOffset, img->mPlane[2].mColInc, img->mPlane[2].mRowInc);
35880d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        }
358903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    }
359003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
359191a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                    if (portIndex != kPortIndexOutput) {
359291a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                        // TODO: also get input crop
359391a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                        break;
359491a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                    }
359591a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar
3596e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_CONFIG_RECTTYPE rect;
3597e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&rect);
359891a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                    rect.nPortIndex = portIndex;
3599e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3600e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    if (mOMX->getConfig(
360191a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                mNode,
360291a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                (portIndex == kPortIndexOutput ?
360391a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                        OMX_IndexConfigCommonOutputCrop :
360491a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                        OMX_IndexConfigCommonInputCrop),
3605e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &rect, sizeof(rect)) != OK) {
3606e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nLeft = 0;
3607e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nTop = 0;
3608e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nWidth = videoDef->nFrameWidth;
3609e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nHeight = videoDef->nFrameHeight;
3610e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    }
361131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3612e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nLeft, 0);
3613e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nTop, 0);
3614e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nWidth, 0u);
3615e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nHeight, 0u);
3616e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_LE(rect.nLeft + rect.nWidth - 1, videoDef->nFrameWidth);
3617e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_LE(rect.nTop + rect.nHeight - 1, videoDef->nFrameHeight);
3618e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3619e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setRect(
3620577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            "crop",
3621577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nLeft,
3622577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nTop,
3623e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                            rect.nLeft + rect.nWidth - 1,
3624e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                            rect.nTop + rect.nHeight - 1);
3625e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3626e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3627e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
36284730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
36294730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP8:
36304730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP9:
36314730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                {
36324730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
36334730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    InitOMXParams(&vp8type);
36344730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    vp8type.nPortIndex = kPortIndexOutput;
36354730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    status_t err = mOMX->getParameter(
36364730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            mNode,
36374730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
36384730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            &vp8type,
36394730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            sizeof(vp8type));
36404730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
36414730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    if (err == OK) {
36424730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        AString tsSchema = "none";
36434730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        if (vp8type.eTemporalPattern
36444730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                == OMX_VIDEO_VPXTemporalLayerPatternWebRTC) {
36454730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            switch (vp8type.nTemporalLayerCount) {
36464730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 1:
36474730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
36484730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.1-layer";
36494730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
36504730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
36514730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 2:
36524730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
36534730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.2-layer";
36544730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
36554730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
36564730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 3:
36574730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
36584730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.3-layer";
36594730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
36604730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
36614730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                default:
36624730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
36634730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
36644730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
36654730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            }
36664730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        }
36674730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        notify->setString("ts-schema", tsSchema);
36684730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    }
36694730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    // Fall through to set up mime.
36704730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                }
36714730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
3672e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                default:
3673e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3674e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(mIsEncoder ^ (portIndex == kPortIndexInput));
3675e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    AString mime;
3676e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    if (GetMimeTypeForVideoCoding(
3677e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        videoDef->eCompressionFormat, &mime) != OK) {
3678e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", "application/octet-stream");
3679e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    } else {
3680e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", mime.c_str());
3681e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    }
3682e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3683e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
368431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            }
3685e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("width", videoDef->nFrameWidth);
3686e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("height", videoDef->nFrameHeight);
36875a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            ALOGV("[%s] %s format is %s", mComponentName.c_str(),
36885a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                    portIndex == kPortIndexInput ? "input" : "output",
36895a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                    notify->debugString().c_str());
36905a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
369131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
369231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
369331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
369431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainAudio:
369531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
369631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
369731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
369897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            switch ((int)audioDef->eEncoding) {
3699e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingPCM:
3700e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3701e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_PCMMODETYPE params;
3702e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3703e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3704e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3705e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3706e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioPcm,
3707e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3708e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3709e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
371014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_GT(params.nChannels, 0);
3711e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK(params.nChannels == 1 || params.bInterleaved);
3712e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(params.nBitPerSample, 16u);
371314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
371414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.eNumData,
371514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_NumericalDataSigned);
371614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
371714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.ePCMMode,
371814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_AUDIO_PCMModeLinear);
3719e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3720e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
3721e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
3722e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSamplingRate);
3723e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3724e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mChannelMaskPresent) {
3725e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("channel-mask", mChannelMask);
37268b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                    }
3727e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
37288b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                }
37299806555d3930be43e11106281dee354820ac1c88Andreas Huber
3730e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAAC:
3731e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3732e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AACPROFILETYPE params;
3733e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3734e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3735e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3736e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3737e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAac,
3738e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3739e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3740e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3741e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
3742e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
3743e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
3744e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
3745e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
3746e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3747e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAMR:
3748e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3749e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AMRTYPE params;
3750e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3751e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
37529806555d3930be43e11106281dee354820ac1c88Andreas Huber
3753e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3754e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAmr,
3755e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3756e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3757e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3758e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", 1);
3759e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) {
3760e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
3761e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_WB);
3762e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3763e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 16000);
3764e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    } else {
3765e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
3766e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
3767e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3768e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 8000);
3769e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
3770e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
3771e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
3772e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3773e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingFLAC:
3774e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3775e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_FLACTYPE params;
3776e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3777e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3778e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3779e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3780e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioFlac,
3781e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3782e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3783e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3784e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC);
3785e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
3786e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
3787e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
3788e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
3789e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3790e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingMP3:
3791e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3792e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_MP3TYPE params;
3793e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
3794e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3795e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3796e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_EQ(mOMX->getParameter(
3797e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                mNode, OMX_IndexParamAudioMp3,
3798e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &params, sizeof(params)),
3799e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                             (status_t)OK);
3800e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3801e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MPEG);
3802e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
3803e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
3804e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3805e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
3806e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3807e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingVORBIS:
3808e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3809e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_VORBISTYPE params;
3810e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
3811e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3812e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3813e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_EQ(mOMX->getParameter(
3814e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                mNode, OMX_IndexParamAudioVorbis,
3815e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &params, sizeof(params)),
3816e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                             (status_t)OK);
3817e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3818e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_VORBIS);
3819e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
3820e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
3821e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3822e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
3823e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
382497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                case OMX_AUDIO_CodingAndroidAC3:
382597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                {
382697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    OMX_AUDIO_PARAM_ANDROID_AC3TYPE params;
382797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    InitOMXParams(&params);
3828e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
382997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
383097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    CHECK_EQ((status_t)OK, mOMX->getParameter(
383197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            mNode,
383297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
383397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            &params,
383497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            sizeof(params)));
383597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
383697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AC3);
383797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("channel-count", params.nChannels);
383897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("sample-rate", params.nSampleRate);
383997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    break;
384097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                }
3841e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
38428a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                case OMX_AUDIO_CodingAndroidEAC3:
38438a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                {
38448a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    OMX_AUDIO_PARAM_ANDROID_EAC3TYPE params;
38458a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    InitOMXParams(&params);
38468a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    params.nPortIndex = portIndex;
38478a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
38488a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    CHECK_EQ((status_t)OK, mOMX->getParameter(
38498a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                            mNode,
38508a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
38518a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                            &params,
38528a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                            sizeof(params)));
38538a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
38548a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_EAC3);
38558a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setInt32("channel-count", params.nChannels);
38568a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setInt32("sample-rate", params.nSampleRate);
38578a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    break;
38588a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                }
38598a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
38608c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                case OMX_AUDIO_CodingAndroidOPUS:
38618c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                {
38628c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    OMX_AUDIO_PARAM_ANDROID_OPUSTYPE params;
38638c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    InitOMXParams(&params);
38648c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    params.nPortIndex = portIndex;
38658c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
38668c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    CHECK_EQ((status_t)OK, mOMX->getParameter(
38678c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            mNode,
38688c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus,
38698c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            &params,
38708c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            sizeof(params)));
38718c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
38728c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_OPUS);
38738c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("channel-count", params.nChannels);
38748c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("sample-rate", params.nSampleRate);
38758c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    break;
38768c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                }
38778c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
387810d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                case OMX_AUDIO_CodingG711:
387910d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                {
388010d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    OMX_AUDIO_PARAM_PCMMODETYPE params;
388110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    InitOMXParams(&params);
388210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    params.nPortIndex = portIndex;
388310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
388410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    CHECK_EQ((status_t)OK, mOMX->getParameter(
388510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                            mNode,
388610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                            (OMX_INDEXTYPE)OMX_IndexParamAudioPcm,
388710d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                            &params,
388810d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                            sizeof(params)));
388910d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
389010d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    const char *mime = NULL;
389110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    if (params.ePCMMode == OMX_AUDIO_PCMModeMULaw) {
389210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_G711_MLAW;
389310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    } else if (params.ePCMMode == OMX_AUDIO_PCMModeALaw) {
389410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_G711_ALAW;
389510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    } else { // params.ePCMMode == OMX_AUDIO_PCMModeLinear
389610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_RAW;
389710d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    }
389810d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setString("mime", mime);
389910d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setInt32("channel-count", params.nChannels);
390010d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setInt32("sample-rate", params.nSamplingRate);
390110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    break;
390210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                }
390341d3f579d2c166984958263533284209b90c87d5Marco Nelissen
390441d3f579d2c166984958263533284209b90c87d5Marco Nelissen                case OMX_AUDIO_CodingGSMFR:
390541d3f579d2c166984958263533284209b90c87d5Marco Nelissen                {
390641d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    OMX_AUDIO_PARAM_MP3TYPE params;
390741d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    InitOMXParams(&params);
390841d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    params.nPortIndex = portIndex;
390941d3f579d2c166984958263533284209b90c87d5Marco Nelissen
391041d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    CHECK_EQ(mOMX->getParameter(
391141d3f579d2c166984958263533284209b90c87d5Marco Nelissen                                mNode, OMX_IndexParamAudioPcm,
391241d3f579d2c166984958263533284209b90c87d5Marco Nelissen                                &params, sizeof(params)),
391341d3f579d2c166984958263533284209b90c87d5Marco Nelissen                             (status_t)OK);
391441d3f579d2c166984958263533284209b90c87d5Marco Nelissen
391541d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MSGSM);
391641d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    notify->setInt32("channel-count", params.nChannels);
391741d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    notify->setInt32("sample-rate", params.nSampleRate);
391841d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    break;
391910d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                }
392010d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
3921e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                default:
3922e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    ALOGE("UNKNOWN AUDIO CODING: %d\n", audioDef->eEncoding);
3923e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    TRESPASS();
3924e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
392531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
392631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
392731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
392831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        default:
392931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            TRESPASS();
393031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    }
393131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3932e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    return OK;
3933e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar}
3934e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3935e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarvoid ACodec::sendFormatChange(const sp<AMessage> &reply) {
39364e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    sp<AMessage> notify = mBaseOutputFormat->dup();
3937e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    notify->setInt32("what", kWhatOutputFormatChanged);
3938e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3939e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ(getPortFormat(kPortIndexOutput, notify), (status_t)OK);
3940e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3941e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    AString mime;
3942e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK(notify->findString("mime", &mime));
3943e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3944e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    int32_t left, top, right, bottom;
3945e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if (mime == MEDIA_MIMETYPE_VIDEO_RAW &&
3946e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        mNativeWindow != NULL &&
3947e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->findRect("crop", &left, &top, &right, &bottom)) {
3948e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        // notify renderer of the crop change
3949e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        // NOTE: native window uses extended right-bottom coordinate
3950e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        reply->setRect("crop", left, top, right + 1, bottom + 1);
3951e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    } else if (mime == MEDIA_MIMETYPE_AUDIO_RAW &&
3952e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar               (mEncoderDelay || mEncoderPadding)) {
3953e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        int32_t channelCount;
3954e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        CHECK(notify->findInt32("channel-count", &channelCount));
3955e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        size_t frameSize = channelCount * sizeof(int16_t);
3956e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        if (mSkipCutBuffer != NULL) {
3957e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            size_t prevbufsize = mSkipCutBuffer->size();
3958e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            if (prevbufsize != 0) {
3959ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                ALOGW("Replacing SkipCutBuffer holding %zu bytes", prevbufsize);
3960e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            }
3961e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        }
3962e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        mSkipCutBuffer = new SkipCutBuffer(
3963e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                mEncoderDelay * frameSize,
3964e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                mEncoderPadding * frameSize);
3965e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
3966e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
396731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->post();
396831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
396931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mSentFormat = true;
397031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber}
397131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
39725778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
3973cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    sp<AMessage> notify = mNotify->dup();
3974d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatError);
3975251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    ALOGE("signalError(omxError %#x, internalError %d)", error, internalError);
3976251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
3977251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (internalError == UNKNOWN_ERROR) { // find better error code
3978251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        const status_t omxStatus = statusFromOMXError(error);
3979251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        if (omxStatus != 0) {
3980251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            internalError = omxStatus;
3981251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        } else {
3982251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            ALOGW("Invalid OMX error %#x", error);
3983251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        }
3984251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
39855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("err", internalError);
3986251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    notify->setInt32("actionCode", ACTION_CODE_FATAL); // could translate from OMX error.
3987cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->post();
3988cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber}
3989cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber
3990bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huberstatus_t ACodec::pushBlankBuffersToNativeWindow() {
3991bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    status_t err = NO_ERROR;
3992bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    ANativeWindowBuffer* anb = NULL;
3993bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int numBufs = 0;
3994bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int minUndequeuedBufs = 0;
3995bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3996bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We need to reconnect to the ANativeWindow as a CPU client to ensure that
3997bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // no frames get dropped by SurfaceFlinger assuming that these are video
3998bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // frames.
3999bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_disconnect(mNativeWindow.get(),
4000bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_MEDIA);
4001bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
4002bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
4003bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
4004bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
4005bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
4006bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4007bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_connect(mNativeWindow.get(),
4008bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_CPU);
4009bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
4010bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
4011bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
4012bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
4013bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
4014bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4015ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    err = native_window_set_buffers_dimensions(mNativeWindow.get(), 1, 1);
4016ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    if (err != NO_ERROR) {
4017ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        ALOGE("error pushing blank frames: set_buffers_dimensions failed: %s (%d)",
4018ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                strerror(-err), -err);
4019ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        goto error;
4020ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    }
4021ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar
4022ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    err = native_window_set_buffers_format(mNativeWindow.get(), HAL_PIXEL_FORMAT_RGBX_8888);
4023bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
4024ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        ALOGE("error pushing blank frames: set_buffers_format failed: %s (%d)",
4025bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
4026bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
4027bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
4028bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
402987eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin    err = native_window_set_scaling_mode(mNativeWindow.get(),
403087eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
403187eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin    if (err != NO_ERROR) {
403287eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin        ALOGE("error pushing blank_frames: set_scaling_mode failed: %s (%d)",
403387eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin              strerror(-err), -err);
403487eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin        goto error;
4035bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
4036bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4037bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_usage(mNativeWindow.get(),
4038bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            GRALLOC_USAGE_SW_WRITE_OFTEN);
4039bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
4040bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_usage failed: %s (%d)",
4041bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
4042bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
4043bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
4044bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4045bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = mNativeWindow->query(mNativeWindow.get(),
4046bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs);
4047bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
4048bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: MIN_UNDEQUEUED_BUFFERS query "
4049bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                "failed: %s (%d)", strerror(-err), -err);
4050bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
4051bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
4052bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4053bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    numBufs = minUndequeuedBufs + 1;
4054bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffer_count(mNativeWindow.get(), numBufs);
4055bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
4056bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffer_count failed: %s (%d)",
4057bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
4058bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
4059bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
4060bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4061bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We  push numBufs + 1 buffers to ensure that we've drawn into the same
4062bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // buffer twice.  This should guarantee that the buffer has been displayed
4063bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // on the screen and then been replaced, so an previous video frames are
4064bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // guaranteed NOT to be currently displayed.
4065bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    for (int i = 0; i < numBufs + 1; i++) {
40661e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &anb);
4067bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
4068bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: dequeueBuffer failed: %s (%d)",
4069bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
4070bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
4071bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
4072bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4073bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
4074bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4075bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Fill the buffer with the a 1x1 checkerboard pattern ;)
4076bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        uint32_t* img = NULL;
4077bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
4078bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
4079bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: lock failed: %s (%d)",
4080bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
4081bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
4082bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
4083bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4084bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        *img = 0;
4085bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4086bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->unlock();
4087bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
4088bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: unlock failed: %s (%d)",
4089bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
4090bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
4091bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
4092bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4093bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->queueBuffer(mNativeWindow.get(),
40941e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                buf->getNativeBuffer(), -1);
4095bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
4096bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: queueBuffer failed: %s (%d)",
4097bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
4098bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
4099bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
4100bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4101bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        anb = NULL;
4102bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
4103bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4104bc098410be55f9d96f394b3981a0c482b83859b6Andreas Hubererror:
4105bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4106bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
4107bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after an error.
4108bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (anb != NULL) {
41091e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis            mNativeWindow->cancelBuffer(mNativeWindow.get(), anb, -1);
4110bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
4111bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4112bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_disconnect(mNativeWindow.get(),
4113bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
4114bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_connect(mNativeWindow.get(),
4115bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
4116bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4117bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
4118bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    } else {
4119bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after success.
4120bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_disconnect(mNativeWindow.get(),
4121bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
4122bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
4123bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
4124bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
4125bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
4126bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
4127bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4128bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_connect(mNativeWindow.get(),
4129bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
4130bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
4131bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
4132bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
4133bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
4134bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
4135bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4136bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return NO_ERROR;
4137bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
4138bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber}
4139bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4142eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberACodec::PortDescription::PortDescription() {
4143eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
4144eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4145496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t ACodec::requestIDRFrame() {
4146496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    if (!mIsEncoder) {
4147496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        return ERROR_UNSUPPORTED;
4148496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    }
4149496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4150496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    OMX_CONFIG_INTRAREFRESHVOPTYPE params;
4151496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    InitOMXParams(&params);
4152496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4153496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.nPortIndex = kPortIndexOutput;
4154496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.IntraRefreshVOP = OMX_TRUE;
4155496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4156496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    return mOMX->setConfig(
4157496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            mNode,
4158496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            OMX_IndexConfigVideoIntraVOPRefresh,
4159496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            &params,
4160496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            sizeof(params));
4161496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
4162496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4163eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubervoid ACodec::PortDescription::addBuffer(
4164eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        IOMX::buffer_id id, const sp<ABuffer> &buffer) {
4165eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBufferIDs.push_back(id);
4166eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBuffers.push_back(buffer);
4167eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
4168eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4169eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersize_t ACodec::PortDescription::countBuffers() {
4170eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.size();
4171eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
4172eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4173eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberIOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const {
4174eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.itemAt(index);
4175eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
4176eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4177eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const {
4178eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBuffers.itemAt(index);
4179eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
4180eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4181eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber////////////////////////////////////////////////////////////////////////////////
4182eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4183f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
4184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : AState(parentState),
4185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mCodec(codec) {
4186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4188ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas HuberACodec::BaseState::PortMode ACodec::BaseState::getPortMode(
4189ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
4190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return KEEP_BUFFERS;
4191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4193f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
4194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatInputBufferFilled:
4196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onInputBufferFilled(msg);
4198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatOutputBufferDrained:
4202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onOutputBufferDrained(msg);
4204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatOMXMessage:
4208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXMessage(msg);
4210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
42127cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
4213d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        case ACodec::kWhatUsePersistentInputSurface:
42147cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
42157cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
4216251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            // This may result in an app illegal state exception.
42177cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            ALOGE("Message 0x%x was not handled", msg->what());
42187cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
42197cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            return true;
42207cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
42217cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4222ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        case ACodec::kWhatOMXDied:
4223ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        {
4224251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            // This will result in kFlagSawMediaServerDie handling in MediaCodec.
4225ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            ALOGE("OMX/mediaserver died, signalling error!");
4226ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT);
4227ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            break;
4228ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        }
4229ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
423030358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        case ACodec::kWhatReleaseCodecInstance:
423130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        {
423230358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            ALOGI("[%s] forcing the release of codec",
423330358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar                    mCodec->mComponentName.c_str());
423430358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            status_t err = mCodec->mOMX->freeNode(mCodec->mNode);
423530358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            ALOGE_IF("[%s] failed to release codec instance: err=%d",
423630358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar                       mCodec->mComponentName.c_str(), err);
423730358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            sp<AMessage> notify = mCodec->mNotify->dup();
423830358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
423930358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            notify->post();
424030358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            break;
424130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        }
424230358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar
4243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
4245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4250f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
4251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t type;
4252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findInt32("type", &type));
4253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
42545e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // there is a possibility that this is an outstanding message for a
42555e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // codec that we have already destroyed
4256ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    if (mCodec->mNode == 0) {
42575e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar        ALOGI("ignoring message as already freed component: %s",
42585e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar                msg->debugString().c_str());
42595e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar        return true;
42605e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    }
42615e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar
4262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::node_id nodeID;
4263609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("node", (int32_t*)&nodeID));
4264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(nodeID, mCodec->mNode);
4265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (type) {
4267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EVENT:
4268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t event, data1, data2;
4270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("event", &event));
4271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data1", &data1));
4272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data2", &data2));
4273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
42740af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            if (event == OMX_EventCmdComplete
42750af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data1 == OMX_CommandFlush
42760af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data2 == (int32_t)OMX_ALL) {
42770af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // Use of this notification is not consistent across
42780af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // implementations. We'll drop this notification and rely
42790af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // on flush-complete notifications on the individual port
42800af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // indices instead.
42810af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
42820af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                return true;
42830af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            }
42840af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
4285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEvent(
4286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_EVENTTYPE>(event),
4287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data1),
4288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data2));
4289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EMPTY_BUFFER_DONE:
4292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
4294609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
4295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEmptyBufferDone(bufferID);
4297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::FILL_BUFFER_DONE:
4300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
4302609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
4303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t rangeOffset, rangeLength, flags;
4305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs;
4306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_offset", &rangeOffset));
4308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_length", &rangeLength));
4309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("flags", &flags));
4310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt64("timestamp", &timeUs));
4311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXFillBufferDone(
4313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    bufferID,
4314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (size_t)rangeOffset, (size_t)rangeLength,
4315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (OMX_U32)flags,
4316784e24e386b088c05d653ab482f2e95cb53e3d01Andy Hung                    timeUs);
4317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
4321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4325f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEvent(
4326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (event != OMX_EventError) {
4328ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        ALOGV("[%s] EVENT(%d, 0x%08x, 0x%08x)",
4329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mCodec->mComponentName.c_str(), event, data1, data2);
4330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return false;
4332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4334ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGE("[%s] ERROR(0x%08x)", mCodec->mComponentName.c_str(), data1);
4335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4336251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // verify OMX component sends back an error we expect.
4337251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    OMX_ERRORTYPE omxError = (OMX_ERRORTYPE)data1;
4338251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (!isOMXError(omxError)) {
4339251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        ALOGW("Invalid OMX error %#x", omxError);
4340251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        omxError = OMX_ErrorUndefined;
4341251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
4342251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    mCodec->signalError(omxError);
4343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4347f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID) {
4348ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGV("[%s] onOMXEmptyBufferDone %u",
4349349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber         mCodec->mComponentName.c_str(), bufferID);
4350349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
4352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexInput, bufferID);
4353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
4355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
4356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
435796e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // We're in "store-metadata-in-buffers" mode, the underlying
435896e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // OMX component had access to data that's implicitly refcounted
435996e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // by this "MediaBuffer" object. Now that the OMX component has
436096e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // told us that it's done with the input buffer, we can decrement
436196e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // the mediaBuffer's reference count.
436296e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    info->mData->setMediaBufferBase(NULL);
4363d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
4365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            postFillThisBuffer(info);
4372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
4377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();  // Not currently used
4378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4385f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
4386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
4387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
4388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
4391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
4393d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatFillThisBuffer);
4394609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    notify->setInt32("buffer-id", info->mBufferID);
4395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mData->meta()->clear();
43972d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    notify->setBuffer("buffer", info->mData);
4398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
43991d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec);
4400609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    reply->setInt32("buffer-id", info->mBufferID);
4401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setMessage("reply", reply);
4403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->post();
4405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
4407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4409f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
4410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
4411609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
44122d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    sp<ABuffer> buffer;
4413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t err = OK;
44145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool eos = false;
4415a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar    PortMode mode = getPortMode(kPortIndexInput);
44165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
44172d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    if (!msg->findBuffer("buffer", &buffer)) {
4418a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar        /* these are unfilled buffers returned by client */
4419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findInt32("err", &err));
4420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
44217fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        if (err == OK) {
44227fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            /* buffers with no errors are returned on MediaCodec.flush */
44237fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            mode = KEEP_BUFFERS;
44247fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        } else {
44257fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            ALOGV("[%s] saw error %d instead of an input buffer",
44267fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                 mCodec->mComponentName.c_str(), err);
44277fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            eos = true;
44287fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        }
44293831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
44302d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber        buffer.clear();
4431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
44335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
44345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
44355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
44365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = ERROR_END_OF_STREAM;
44375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
44385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
4440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_UPSTREAM);
4441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
4443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
44475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (eos) {
4448dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (!mCodec->mPortEOS[kPortIndexInput]) {
4449dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
4450dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mInputEOSResult = err;
4451dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
4452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
44585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
4459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int64_t timeUs;
4460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
4461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
4463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t isCSD;
4465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
4466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
4467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
4468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
44695778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (eos) {
44705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    flags |= OMX_BUFFERFLAG_EOS;
44715778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
44725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer != info->mData) {
4474ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] Needs to copy input data for buffer %u. (%p != %p)",
4475d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(),
4476d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         bufferID,
4477d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         buffer.get(), info->mData.get());
4478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    CHECK_LE(buffer->size(), info->mData->capacity());
4480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    memcpy(info->mData->data(), buffer->data(), buffer->size());
4481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
4482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4483078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
4484ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] calling emptyBuffer %u w/ codec specific data",
4485078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID);
44865778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else if (flags & OMX_BUFFERFLAG_EOS) {
4487ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] calling emptyBuffer %u w/ EOS",
44885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str(), bufferID);
4489078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                } else {
4490d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
4491ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGI("[%s] calling emptyBuffer %u w/ time %lld us",
4492ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                         mCodec->mComponentName.c_str(), bufferID, (long long)timeUs);
4493d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#else
4494ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] calling emptyBuffer %u w/ time %lld us",
4495ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                         mCodec->mComponentName.c_str(), bufferID, (long long)timeUs);
4496d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
4497078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                }
4498349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4499d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
4500d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ACodec::BufferStats stats;
4501d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
4502d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mFillBufferDoneTimeUs = -1ll;
4503d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mCodec->mBufferStats.add(timeUs, stats);
4504d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
4505d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4506054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                if (mCodec->mStoreMetaDataInOutputBuffers) {
4507054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    // try to submit an output buffer for each input buffer
4508054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    PortMode outputMode = getPortMode(kPortIndexOutput);
4509054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4510054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    ALOGV("MetaDataBuffersToSubmit=%u portMode=%s",
4511054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            mCodec->mMetaDataBuffersToSubmit,
4512054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            (outputMode == FREE_BUFFERS ? "FREE" :
4513054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                             outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
4514054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    if (outputMode == RESUBMIT_BUFFERS) {
4515e53350373ac516257b4f8956ff1e3f1ac48f607eLajos Molnar                        mCodec->submitOutputMetaDataBuffer();
4516054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    }
4517054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                }
4518054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
4520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
4521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
4522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
4523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            buffer->size(),
4524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            flags,
4525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            timeUs),
4526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
45305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (!eos) {
45315778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    getMoreInputDataIfPossible();
45325778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
45335778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] Signalled EOS on the input port",
45345778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str());
45355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
45365778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
45375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mInputEOSResult = err;
45385778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
4539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
4540dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (err != ERROR_END_OF_STREAM) {
45413856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port "
4542dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         "due to error %d",
4543dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str(), err);
4544dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                } else {
45453856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port",
4546dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str());
4547dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
4548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4549ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                ALOGV("[%s] calling emptyBuffer %u signalling EOS",
4550349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                     mCodec->mComponentName.c_str(), bufferID);
4551349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
4553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
4554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
4555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
4556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
4557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_BUFFERFLAG_EOS,
4558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0),
4559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexInput] = true;
4564dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                mCodec->mInputEOSResult = err;
4565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4568625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih
4569625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih        default:
4570625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
4571625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih            break;
4572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4575f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::getMoreInputDataIfPossible() {
4576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
4577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
4578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *eligible = NULL;
4581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
4583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
4584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
4586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
4587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // There's already a "read" pending.
4588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
4589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
4591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_US) {
4593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            eligible = info;
4594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (eligible == NULL) {
4598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
4599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(eligible);
4602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4604f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXFillBufferDone(
4605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferID,
4606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        size_t rangeOffset, size_t rangeLength,
4607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 flags,
4608784e24e386b088c05d653ab482f2e95cb53e3d01Andy Hung        int64_t timeUs) {
4609609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] onOMXFillBufferDone %u time %" PRId64 " us, flags = 0x%08x",
46105778822d86b0337407514b9372562b86edfa91cdAndreas Huber         mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
4611349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
4613d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4614d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
4615d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    index = mCodec->mBufferStats.indexOfKey(timeUs);
4616d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (index >= 0) {
4617d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
4618d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
4619d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4620d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ALOGI("frame PTS %lld: %lld",
4621d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                timeUs,
4622d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
4623d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4624d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mCodec->mBufferStats.removeItemsAt(index);
4625d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats = NULL;
4626d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
4627d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
4628d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
4630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
4631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
4633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4634054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mDequeuedAt = ++mCodec->mDequeueCounter;
4635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
4636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
4638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4645a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            if (rangeLength == 0 && (!(flags & OMX_BUFFERFLAG_EOS)
4646a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                    || mCodec->mPortEOS[kPortIndexOutput])) {
4647609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                ALOGV("[%s] calling fillBuffer %u",
46485778822d86b0337407514b9372562b86edfa91cdAndreas Huber                     mCodec->mComponentName.c_str(), info->mBufferID);
4649349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
46505778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK_EQ(mCodec->mOMX->fillBuffer(
46515778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mCodec->mNode, info->mBufferID),
46525778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         (status_t)OK);
4653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
46545778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
46555778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
46565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
465731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4658577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            sp<AMessage> reply =
46591d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar                new AMessage(kWhatOutputBufferDrained, mCodec);
4660577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
46614bdda35319d5f46efea2089b865c8a64816389cdMarco Nelissen            if (!mCodec->mSentFormat && rangeLength > 0) {
4662577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->sendFormatChange(reply);
46635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
4664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4665308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            if (mCodec->mUseMetadataOnEncoderOutput) {
4666308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                native_handle_t* handle =
4667308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        *(native_handle_t**)(info->mData->data() + 4);
4668308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setPointer("handle", handle);
4669308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeOffset", rangeOffset);
4670308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeLength", rangeLength);
4671308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            } else {
4672308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->setRange(rangeOffset, rangeLength);
4673308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            }
4674496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#if 0
467521ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen            if (mCodec->mNativeWindow == NULL) {
4676496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                if (IsIDR(info->mData)) {
4677496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                    ALOGI("IDR frame");
4678496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                }
46795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
468021ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen#endif
4681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
46828b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            if (mCodec->mSkipCutBuffer != NULL) {
46838b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                mCodec->mSkipCutBuffer->submit(info->mData);
46848b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            }
46855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mData->meta()->setInt64("timeUs", timeUs);
4686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
46875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4688d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatDrainThisBuffer);
4689609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            notify->setInt32("buffer-id", info->mBufferID);
46902d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            notify->setBuffer("buffer", info->mData);
46915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("flags", flags);
4692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4693609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            reply->setInt32("buffer-id", info->mBufferID);
4694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
46955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setMessage("reply", reply);
4696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
46975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->post();
46985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
46995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
4700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (flags & OMX_BUFFERFLAG_EOS) {
47025778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
47035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                sp<AMessage> notify = mCodec->mNotify->dup();
4705d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar                notify->setInt32("what", CodecBase::kWhatEOS);
4706dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                notify->setInt32("err", mCodec->mInputEOSResult);
4707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->post();
4708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexOutput] = true;
4710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
4717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
4719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
4720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4727f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
4728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
4729609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
4730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
4731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
4732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
4733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM);
4734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4735577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    android_native_rect_t crop;
4736577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    if (msg->findRect("crop",
4737577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            &crop.left, &crop.top, &crop.right, &crop.bottom)) {
4738577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar        CHECK_EQ(0, native_window_set_crop(
4739577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->mNativeWindow.get(), &crop));
4740577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    }
4741577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
4742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t render;
4743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mNativeWindow != NULL
47446aade6058521b0dbd35a9a4620f4d04f02f90444Marco Nelissen            && msg->findInt32("render", &render) && render != 0
474579ee2399b67c7a11042c5904dc1309712a76f8cbJianzheng Zhou            && info->mData != NULL && info->mData->size() != 0) {
47466fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        ATRACE_NAME("render");
4747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The client wants this buffer to be rendered.
4748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4749fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        int64_t timestampNs = 0;
4750fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        if (!msg->findInt64("timestampNs", &timestampNs)) {
4751fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // TODO: it seems like we should use the timestamp
4752fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // in the (media)buffer as it potentially came from
4753fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // an input surface, but we did not propagate it prior to
4754fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // API 20.  Perhaps check for target SDK version.
4755fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#if 0
4756fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            if (info->mData->meta()->findInt64("timeUs", &timestampNs)) {
475747aea1f7c58f5302b16822f9e7e1763f2af04ef5Lajos Molnar                ALOGV("using buffer PTS of %" PRId64, timestampNs);
4758fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar                timestampNs *= 1000;
4759fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            }
4760fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#endif
4761fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
4762fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
47635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err;
4764fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        err = native_window_set_buffers_timestamp(mCodec->mNativeWindow.get(), timestampNs);
4765fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        if (err != OK) {
4766fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            ALOGW("failed to set buffer timestamp: %d", err);
4767fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
4768fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
47695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if ((err = mCodec->mNativeWindow->queueBuffer(
4770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNativeWindow.get(),
47711e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                    info->mGraphicBuffer.get(), -1)) == OK) {
4772cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
4773cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        } else {
4774251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
4775cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
4776cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        }
4777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
47786fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        if (mCodec->mNativeWindow != NULL &&
47796fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar            (info->mData == NULL || info->mData->size() != 0)) {
47806fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar            ATRACE_NAME("frame-drop");
47816fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        }
4782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_US;
4783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
4786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
4791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // We cannot resubmit the buffer we just rendered, dequeue
4794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // the spare instead.
4795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info = mCodec->dequeueBufferFromNativeWindow();
4797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (!mCodec->mPortEOS[kPortIndexOutput]) {
4804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // We cannot resubmit the buffer we just rendered, dequeue
4806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // the spare instead.
4807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info = mCodec->dequeueBufferFromNativeWindow();
4809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
4810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4811c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                if (info != NULL) {
4812609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                    ALOGV("[%s] calling fillBuffer %u",
4813c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                         mCodec->mComponentName.c_str(), info->mBufferID);
4814349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4815c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
4816c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                             (status_t)OK);
4817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4818c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4819c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                }
4820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
4827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
4829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
4830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4837f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::UninitializedState::UninitializedState(ACodec *codec)
4838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4840f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4841c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::UninitializedState::stateEntered() {
4842c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("Now uninitialized");
4843ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4844ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (mDeathNotifier != NULL) {
4845f888020c6e2735624f2b2a30e72aca24e17b8b4dMarco Nelissen        IInterface::asBinder(mCodec->mOMX)->unlinkToDeath(mDeathNotifier);
4846ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
4847ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
4848ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4849ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNativeWindow.clear();
4850ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    mCodec->mNode = 0;
4851ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mOMX.clear();
4852ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mQuirks = 0;
4853ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mFlags = 0;
4854308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    mCodec->mUseMetadataOnEncoderOutput = 0;
4855ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mComponentName.clear();
4856c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4857c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4858f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
4859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatSetup:
4863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onSetup(msg);
4865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
48705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case ACodec::kWhatAllocateComponent:
48715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
48725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            onAllocateComponent(msg);
48735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            handled = true;
48745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
48755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
48765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatShutdown:
4878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4879c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
4880c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
4881c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
488254b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            ALOGW_IF(keepComponentAllocated,
488354b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar                     "cannot keep component allocated on shutdown in Uninitialized state");
4884c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4886d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
4887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
4888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4890c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
4891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatFlush:
4894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4896d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
4897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
4898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4900c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
4901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
490330358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        case ACodec::kWhatReleaseCodecInstance:
490430358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        {
490530358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            // nothing to do, as we have already signaled shutdown
490630358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            handled = true;
490730358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            break;
490830358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        }
490930358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar
4910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
4912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4917f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::UninitializedState::onSetup(
4918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4919c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (onAllocateComponent(msg)
4920c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            && mCodec->mLoadedState->onConfigureComponent(msg)) {
4921c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mLoadedState->onStart();
4922c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
49235778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
49245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4925c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
49265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onAllocateComponent");
49275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4928ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    CHECK(mCodec->mNode == 0);
49295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMXClient client;
493148a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung    if (client.connect() != OK) {
493248a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung        mCodec->signalError(OMX_ErrorUndefined, NO_INIT);
493348a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung        return false;
493448a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung    }
4935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<IOMX> omx = client.interface();
4937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
49381d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec);
4939ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4940ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mDeathNotifier = new DeathNotifier(notify);
4941f888020c6e2735624f2b2a30e72aca24e17b8b4dMarco Nelissen    if (IInterface::asBinder(omx)->linkToDeath(mDeathNotifier) != OK) {
4942ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // This was a local binder, if it dies so do we, we won't care
4943ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // about any notifications in the afterlife.
4944ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
4945ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
4946ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4947e671207115fac3914134c61b336d5fa0242c68caAndreas Huber    Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs;
49485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    AString mime;
4950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
49515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString componentName;
4952d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint32_t quirks = 0;
49537791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen    int32_t encoder = false;
49545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findString("componentName", &componentName)) {
4955e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        ssize_t index = matchingCodecs.add();
4956e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        OMXCodec::CodecNameAndQuirks *entry = &matchingCodecs.editItemAt(index);
4957e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        entry->mName = String8(componentName.c_str());
4958afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
4959e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        if (!OMXCodec::findCodecQuirks(
4960e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                    componentName.c_str(), &entry->mQuirks)) {
4961e671207115fac3914134c61b336d5fa0242c68caAndreas Huber            entry->mQuirks = 0;
4962afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
49635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
49645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(msg->findString("mime", &mime));
49655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
49665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("encoder", &encoder)) {
49675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder = false;
49685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
49695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
49705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMXCodec::findMatchingCodecs(
49715778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mime.c_str(),
49725778822d86b0337407514b9372562b86edfa91cdAndreas Huber                encoder, // createEncoder
49735778822d86b0337407514b9372562b86edfa91cdAndreas Huber                NULL,  // matchComponentName
49745778822d86b0337407514b9372562b86edfa91cdAndreas Huber                0,     // flags
4975e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                &matchingCodecs);
49765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
49771065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
49781065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    sp<CodecObserver> observer = new CodecObserver;
4979ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    IOMX::node_id node = 0;
49801065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
49819f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu    status_t err = OMX_ErrorComponentNotFound;
49821065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
49831065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            ++matchIndex) {
4984e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        componentName = matchingCodecs.itemAt(matchIndex).mName.string();
4985e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        quirks = matchingCodecs.itemAt(matchIndex).mQuirks;
4986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4987da153975581fb3161a30452348a5b26ee72d9255Elliott Hughes        pid_t tid = gettid();
4988078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        int prevPriority = androidGetThreadPriority(tid);
4989078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
49909f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu        err = omx->allocateNode(componentName.c_str(), observer, &node);
4991078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, prevPriority);
4992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
49931065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        if (err == OK) {
49941065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            break;
49957a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He        } else {
49967a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He            ALOGW("Allocating component '%s' failed, try next one.", componentName.c_str());
49971065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
49981065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
4999ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        node = 0;
50001065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    }
50011065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
5002ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    if (node == 0) {
50035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!mime.empty()) {
50049f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu            ALOGE("Unable to instantiate a %scoder for type '%s' with err %#x.",
50059f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu                    encoder ? "en" : "de", mime.c_str(), err);
50065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
50079f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu            ALOGE("Unable to instantiate codec '%s' with err %#x.", componentName.c_str(), err);
50085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
5009c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
501052e88b2986536e83a7a6da63461556b8734a85f3Ronghua Wu        mCodec->signalError((OMX_ERRORTYPE)err, makeNoSideEffectStatus(err));
5011c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
5012c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
5013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
50141d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    notify = new AMessage(kWhatOMXMessage, mCodec);
5015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    observer->setNotificationMessage(notify);
5016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mComponentName = componentName;
5018ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    mCodec->mFlags = 0;
5019ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
5020ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (componentName.endsWith(".secure")) {
5021ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        mCodec->mFlags |= kFlagIsSecure;
50221713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        mCodec->mFlags |= kFlagIsGrallocUsageProtected;
50230167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
5024ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
5025ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
5026afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mCodec->mQuirks = quirks;
5027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mOMX = omx;
5028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mNode = node;
5029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
50305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
50315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
5032d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatComponentAllocated);
50335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setString("componentName", mCodec->mComponentName.c_str());
50345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
50355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5036c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5037c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mCodec->changeState(mCodec->mLoadedState);
5038c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5039c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
50405778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
50415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5042c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
5043c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5044c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas HuberACodec::LoadedState::LoadedState(ACodec *codec)
5045c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    : BaseState(codec) {
5046c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
5047c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5048c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::stateEntered() {
5049c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
5050c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5051f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mPortEOS[kPortIndexInput] =
5052f6f38287b97ec69b169387add6458f859b770e65Andreas Huber        mCodec->mPortEOS[kPortIndexOutput] = false;
5053f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
5054f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mInputEOSResult = OK;
5055f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
5056054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mDequeueCounter = 0;
5057054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mMetaDataBuffersToSubmit = 0;
5058a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    mCodec->mRepeatFrameDelayUs = -1ll;
5059e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mInputFormat.clear();
5060e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mOutputFormat.clear();
50614e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    mCodec->mBaseOutputFormat.clear();
5062054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5063c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (mCodec->mShutdownInProgress) {
5064c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
5065c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5066c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mShutdownInProgress = false;
5067c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mKeepComponentAllocated = false;
5068c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5069c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        onShutdown(keepComponentAllocated);
5070c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
507154b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    mCodec->mExplicitShutdown = false;
5072f393c33e65ae51a7cf168b4e15771b152f996b32Wei Jia
5073f393c33e65ae51a7cf168b4e15771b152f996b32Wei Jia    mCodec->processDeferredMessages();
5074c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
5075c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5076c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
5077c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (!keepComponentAllocated) {
5078c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK);
5079c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5080c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->changeState(mCodec->mUninitializedState);
5081c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
5082c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
508354b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    if (mCodec->mExplicitShutdown) {
508454b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        sp<AMessage> notify = mCodec->mNotify->dup();
5085d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
508654b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        notify->post();
508754b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        mCodec->mExplicitShutdown = false;
508854b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    }
5089c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
5090c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5091c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
5092c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool handled = false;
5093c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5094c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    switch (msg->what()) {
5095c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatConfigureComponent:
5096c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
5097c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onConfigureComponent(msg);
5098c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
5099c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
5100c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
5101c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
51027cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
51037cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
51047cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            onCreateInputSurface(msg);
51057cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
51067cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
51077cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
51087cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
5109d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        case ACodec::kWhatUsePersistentInputSurface:
5110d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        {
5111d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            onUsePersistentInputSurface(msg);
5112d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            handled = true;
5113d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            break;
5114d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        }
5115d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5116c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatStart:
5117c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
5118c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onStart();
5119c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
5120c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
5121c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
5122c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5123c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatShutdown:
5124c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
5125c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
5126c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
5127c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
5128c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
512954b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
5130c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onShutdown(keepComponentAllocated);
5131c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5132c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
5133c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
5134c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
5135c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5136c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatFlush:
5137c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
5138c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
5139d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
5140c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->post();
5141c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5142c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
5143c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
5144c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
5145c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5146c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        default:
5147c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            return BaseState::onMessageReceived(msg);
5148c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
5149c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5150c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return handled;
5151c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
5152c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5153c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onConfigureComponent(
51545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg) {
51555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onConfigureComponent");
51565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5157ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    CHECK(mCodec->mNode != 0);
51585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
51595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString mime;
51605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findString("mime", &mime));
51615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
51625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mCodec->configureCodec(mime.c_str(), msg);
51635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
51645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
5165c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        ALOGE("[%s] configureCodec returning error %d",
5166c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber              mCodec->mComponentName.c_str(), err);
5167c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber
5168251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5169c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
51705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
51725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
51735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
5174d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatComponentConfigured);
5175e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("input-format", mCodec->mInputFormat);
5176e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("output-format", mCodec->mOutputFormat);
51775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
51785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5179c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5180c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
51815778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
51825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5183d291c222357303b9611cab89d0c3b047584ef377Chong Zhangstatus_t ACodec::LoadedState::setupInputSurface() {
5184d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    status_t err = OK;
5185a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
5186d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mRepeatFrameDelayUs > 0ll) {
5187a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        err = mCodec->mOMX->setInternalOption(
5188a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                mCodec->mNode,
5189a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                kPortIndexInput,
5190a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY,
5191a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                &mCodec->mRepeatFrameDelayUs,
5192a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                sizeof(mCodec->mRepeatFrameDelayUs));
5193a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
5194a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (err != OK) {
5195a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            ALOGE("[%s] Unable to configure option to repeat previous "
5196a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  "frames (err %d)",
5197a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  mCodec->mComponentName.c_str(),
5198a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  err);
5199d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
5200a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
5201a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
5202a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
5203d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mMaxPtsGapUs > 0ll) {
520494ee4b708acfa941581160b267afb79192b1d816Chong Zhang        err = mCodec->mOMX->setInternalOption(
520594ee4b708acfa941581160b267afb79192b1d816Chong Zhang                mCodec->mNode,
520694ee4b708acfa941581160b267afb79192b1d816Chong Zhang                kPortIndexInput,
520794ee4b708acfa941581160b267afb79192b1d816Chong Zhang                IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP,
520894ee4b708acfa941581160b267afb79192b1d816Chong Zhang                &mCodec->mMaxPtsGapUs,
520994ee4b708acfa941581160b267afb79192b1d816Chong Zhang                sizeof(mCodec->mMaxPtsGapUs));
521094ee4b708acfa941581160b267afb79192b1d816Chong Zhang
521194ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (err != OK) {
521294ee4b708acfa941581160b267afb79192b1d816Chong Zhang            ALOGE("[%s] Unable to configure max timestamp gap (err %d)",
521372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    mCodec->mComponentName.c_str(),
521472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    err);
5215d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
52162c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
52172c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
52182c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
5219d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mMaxFps > 0) {
522037b2b389139ed638831e49708c947863eef631efRonghua Wu        err = mCodec->mOMX->setInternalOption(
522137b2b389139ed638831e49708c947863eef631efRonghua Wu                mCodec->mNode,
522237b2b389139ed638831e49708c947863eef631efRonghua Wu                kPortIndexInput,
522337b2b389139ed638831e49708c947863eef631efRonghua Wu                IOMX::INTERNAL_OPTION_MAX_FPS,
522437b2b389139ed638831e49708c947863eef631efRonghua Wu                &mCodec->mMaxFps,
522537b2b389139ed638831e49708c947863eef631efRonghua Wu                sizeof(mCodec->mMaxFps));
522637b2b389139ed638831e49708c947863eef631efRonghua Wu
522737b2b389139ed638831e49708c947863eef631efRonghua Wu        if (err != OK) {
522837b2b389139ed638831e49708c947863eef631efRonghua Wu            ALOGE("[%s] Unable to configure max fps (err %d)",
522937b2b389139ed638831e49708c947863eef631efRonghua Wu                    mCodec->mComponentName.c_str(),
523037b2b389139ed638831e49708c947863eef631efRonghua Wu                    err);
5231d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
523237b2b389139ed638831e49708c947863eef631efRonghua Wu        }
523337b2b389139ed638831e49708c947863eef631efRonghua Wu    }
523437b2b389139ed638831e49708c947863eef631efRonghua Wu
5235d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mTimePerCaptureUs > 0ll
52362c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            && mCodec->mTimePerFrameUs > 0ll) {
52372c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        int64_t timeLapse[2];
52382c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[0] = mCodec->mTimePerFrameUs;
52392c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[1] = mCodec->mTimePerCaptureUs;
52402c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        err = mCodec->mOMX->setInternalOption(
52412c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                mCodec->mNode,
52422c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                kPortIndexInput,
52432c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                IOMX::INTERNAL_OPTION_TIME_LAPSE,
52442c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                &timeLapse[0],
52452c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                sizeof(timeLapse));
52462c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
52472c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (err != OK) {
52482c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            ALOGE("[%s] Unable to configure time lapse (err %d)",
52492c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    mCodec->mComponentName.c_str(),
52502c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    err);
5251d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
52522c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
52532c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
525472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
5255d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mCreateInputBuffersSuspended) {
525672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        bool suspend = true;
525772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        err = mCodec->mOMX->setInternalOption(
525872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                mCodec->mNode,
525972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                kPortIndexInput,
526072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                IOMX::INTERNAL_OPTION_SUSPEND,
526172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                &suspend,
526272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                sizeof(suspend));
526372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
526472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
526572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("[%s] Unable to configure option to suspend (err %d)",
526694ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  mCodec->mComponentName.c_str(),
526794ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  err);
5268d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
526994ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
527094ee4b708acfa941581160b267afb79192b1d816Chong Zhang    }
527194ee4b708acfa941581160b267afb79192b1d816Chong Zhang
5272d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    return OK;
5273d291c222357303b9611cab89d0c3b047584ef377Chong Zhang}
5274d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5275d291c222357303b9611cab89d0c3b047584ef377Chong Zhangvoid ACodec::LoadedState::onCreateInputSurface(
5276d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        const sp<AMessage> & /* msg */) {
5277d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    ALOGV("onCreateInputSurface");
5278d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5279d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<AMessage> notify = mCodec->mNotify->dup();
5280d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    notify->setInt32("what", CodecBase::kWhatInputSurfaceCreated);
5281d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5282d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<IGraphicBufferProducer> bufferProducer;
5283d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    status_t err = mCodec->mOMX->createInputSurface(
5284d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            mCodec->mNode, kPortIndexInput, &bufferProducer);
5285d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5286d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (err == OK) {
5287d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        err = setupInputSurface();
5288d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    }
5289d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
52907cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err == OK) {
52917cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setObject("input-surface",
52927cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                new BufferProducerWrapper(bufferProducer));
52937cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else {
52947cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // Can't use mCodec->signalError() here -- MediaCodec won't forward
52957cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // the error through because it's in the "configured" state.  We
52967cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // send a kWhatInputSurfaceCreated with an error value instead.
52977cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGE("[%s] onCreateInputSurface returning error %d",
52987cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                mCodec->mComponentName.c_str(), err);
52997cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setInt32("err", err);
53007cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
53017cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->post();
53027cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
53037cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
5304d291c222357303b9611cab89d0c3b047584ef377Chong Zhangvoid ACodec::LoadedState::onUsePersistentInputSurface(
5305d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        const sp<AMessage> &msg) {
5306d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    ALOGV("onUsePersistentInputSurface");
5307d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5308d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<AMessage> notify = mCodec->mNotify->dup();
5309d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    notify->setInt32("what", CodecBase::kWhatInputSurfaceAccepted);
5310d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5311d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<RefBase> obj;
5312d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    CHECK(msg->findObject("input-surface", &obj));
5313d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<PersistentSurface> surface = static_cast<PersistentSurface *>(obj.get());
5314d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5315d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    status_t err = mCodec->mOMX->usePersistentInputSurface(
5316d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            mCodec->mNode, kPortIndexInput, surface->getBufferConsumer());
5317d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5318d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (err == OK) {
5319d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        err = setupInputSurface();
5320d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    }
5321d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5322d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (err != OK) {
5323d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        // Can't use mCodec->signalError() here -- MediaCodec won't forward
5324d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        // the error through because it's in the "configured" state.  We
5325d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        // send a kWhatInputSurfaceAccepted with an error value instead.
5326d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        ALOGE("[%s] onUsePersistentInputSurface returning error %d",
5327d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                mCodec->mComponentName.c_str(), err);
5328d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        notify->setInt32("err", err);
5329d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    }
5330d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    notify->post();
5331d291c222357303b9611cab89d0c3b047584ef377Chong Zhang}
5332d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5333c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onStart() {
53345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onStart");
53355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
53365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ(mCodec->mOMX->sendCommand(
53375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
5338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
5339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->changeState(mCodec->mLoadedToIdleState);
5341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5345f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
5346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5349f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::LoadedToIdleState::stateEntered() {
53503856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
5351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5352cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    status_t err;
5353cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    if ((err = allocateBuffers()) != OK) {
535429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to allocate buffers after transitioning to IDLE state "
5355cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             "(error 0x%08x)",
5356cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             err);
5357cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
5358251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
535991bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber
536091bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber        mCodec->changeState(mCodec->mLoadedState);
5361cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    }
5362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5364f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::LoadedToIdleState::allocateBuffers() {
5365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
5366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
5368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
5369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mCodec->allocateBuffersOnPort(kPortIndexOutput);
5372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5374f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
5375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
537672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
5377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
5380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
53836507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
53846507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
53856507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
53866507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
53876507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
53886507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
53896463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatResume:
53906463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
53916463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We'll be active soon enough.
53926463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
53936463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
53946463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
53956463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatFlush:
53966463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
53976463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We haven't even started yet, so we're flushed alright...
53986463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            sp<AMessage> notify = mCodec->mNotify->dup();
5399d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
54006463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->post();
54016463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
54026463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
54036463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
5404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
5406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5409f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onOMXEvent(
5410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
5415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
5416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
5418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting),
5419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
5420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mIdleToExecutingState);
5422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5433f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
5434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5437f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToExecutingState::stateEntered() {
54383856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
5439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5441f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
5442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
544372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
5444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
5447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5450d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatResume:
5451d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
5452d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We'll be active soon enough.
5453d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
5454d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
5455d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
5456d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatFlush:
5457d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
5458d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We haven't even started yet, so we're flushed alright...
5459d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
5460d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
5461d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->post();
5462d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
5463d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
5464d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
5465d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
54666507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
54676507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
54686507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
54696507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
54706507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
54716507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
5472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
5474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5477f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onOMXEvent(
5478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
5483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateExecuting);
5484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mExecutingState->resume();
5486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingState);
5487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5498f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingState::ExecutingState(ACodec *codec)
5499349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    : BaseState(codec),
5500349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber      mActive(false) {
5501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5503f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
5504ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
5505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
5506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5508054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputMetaBuffers() {
5509054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // submit as many buffers as there are input buffers with the codec
5510054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // in case we are in port reconfiguring
5511054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
5512054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
5513054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5514054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) {
5515054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            if (mCodec->submitOutputMetaDataBuffer() != OK)
5516054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                break;
5517054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
5518054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
55194dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
55204dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
55214dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
5522054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
5523054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5524054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitRegularOutputBuffers() {
5525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
5526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
5527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mCodec->mNativeWindow != NULL) {
5529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(info->mStatus == BufferInfo::OWNED_BY_US
5530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
5531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
5533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                continue;
5534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
5536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
5537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5539ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        ALOGV("[%s] calling fillBuffer %u",
5540349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str(), info->mBufferID);
5541349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
5543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
5544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
5546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5549054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputBuffers() {
5550c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar    submitRegularOutputBuffers();
5551054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mCodec->mStoreMetaDataInOutputBuffers) {
5552054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        submitOutputMetaBuffers();
5553054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
5554054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
5555054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5556f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::resume() {
5557349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    if (mActive) {
55583856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] We're already active, no need to resume.",
5559349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str());
5560349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5561349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        return;
5562349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    }
5563349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    submitOutputBuffers();
5565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
55663cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    // Post all available input buffers
5567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_GT(mCodec->mBuffers[kPortIndexInput].size(), 0u);
55683cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); i++) {
55693cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
55703cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_US) {
55713cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar            postFillThisBuffer(info);
55723cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        }
55733cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    }
5574349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5575349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    mActive = true;
5576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5578f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::stateEntered() {
55793856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
5580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->processDeferredMessages();
5582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5584f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
5585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5590c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
5591c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
5592c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
5593c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5594c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mShutdownInProgress = true;
559554b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
5596c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mKeepComponentAllocated = keepComponentAllocated;
5597c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5598349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
5599349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
5601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
5602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
5603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingToIdleState);
5605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
56127a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong            ALOGV("[%s] ExecutingState flushing now "
5613ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                 "(codec owns %zu/%zu input, %zu/%zu output).",
5614d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mComponentName.c_str(),
5615d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
5616d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexInput].size(),
5617d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
5618d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexOutput].size());
5619d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
5620349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
5621349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
5623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandFlush, OMX_ALL),
5624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
5625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mFlushingState);
5627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatResume:
5632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            resume();
5634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5639496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
5640496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
5641496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            status_t err = mCodec->requestIDRFrame();
5642496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            if (err != OK) {
5643496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                ALOGW("Requesting an IDR frame failed.");
5644496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            }
5645496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5646496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            handled = true;
5647496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
5648496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
5649496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5650a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
5651a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
5652a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
5653a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
5654a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5655a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = mCodec->setParameters(params);
5656a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5657a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> reply;
5658a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            if (msg->findMessage("reply", &reply)) {
5659a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->setInt32("err", err);
5660a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->post();
5661a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            }
5662a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5663a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            handled = true;
5664a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
5665a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
5666a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
56677cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
56687cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
56696507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
56707cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
56717cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
56727cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
56737cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
56744dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
56754dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        case kWhatSubmitOutputMetaDataBufferIfEOS:
56764dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        {
56774dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            if (mCodec->mPortEOS[kPortIndexInput] &&
56784dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    !mCodec->mPortEOS[kPortIndexOutput]) {
56794dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                status_t err = mCodec->submitOutputMetaDataBuffer();
56804dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                if (err == OK) {
56814dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
56824dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                }
56834dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            }
56844dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            return true;
56854dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        }
56864dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
5687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5695a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t ACodec::setParameters(const sp<AMessage> &params) {
5696a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    int32_t videoBitrate;
5697530fdbdc1b5491f3fbf172752834d1515701e142Lajos Molnar    if (params->findInt32("video-bitrate", &videoBitrate)) {
5698a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        OMX_VIDEO_CONFIG_BITRATETYPE configParams;
5699a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        InitOMXParams(&configParams);
5700a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nPortIndex = kPortIndexOutput;
5701a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nEncodeBitrate = videoBitrate;
5702a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5703a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        status_t err = mOMX->setConfig(
5704a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                mNode,
5705a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                OMX_IndexConfigVideoBitrate,
5706a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                &configParams,
5707a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                sizeof(configParams));
5708a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5709a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        if (err != OK) {
5710a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
5711a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                   videoBitrate, err);
5712a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5713a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            return err;
5714a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
5715a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    }
5716a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
571772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    int64_t skipFramesBeforeUs;
571872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (params->findInt64("skip-frames-before", &skipFramesBeforeUs)) {
571972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        status_t err =
572072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mOMX->setInternalOption(
572172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     mNode,
572272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     kPortIndexInput,
572372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     IOMX::INTERNAL_OPTION_START_TIME,
572472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     &skipFramesBeforeUs,
572572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     sizeof(skipFramesBeforeUs));
572672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
572772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
572872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("Failed to set parameter 'skip-frames-before' (err %d)", err);
572972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            return err;
573072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
573172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
573272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
5733e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    int32_t dropInputFrames;
5734e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    if (params->findInt32("drop-input-frames", &dropInputFrames)) {
5735e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        bool suspend = dropInputFrames != 0;
5736e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
5737b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err =
5738b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            mOMX->setInternalOption(
5739e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     mNode,
5740e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     kPortIndexInput,
5741e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     IOMX::INTERNAL_OPTION_SUSPEND,
5742e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     &suspend,
5743b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber                     sizeof(suspend));
5744b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
5745b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
5746b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err);
5747b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
5748b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
5749b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    }
5750b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
5751b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    int32_t dummy;
5752b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    if (params->findInt32("request-sync", &dummy)) {
5753b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err = requestIDRFrame();
5754b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
5755b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
5756b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Requesting a sync frame failed w/ err %d", err);
5757b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
5758b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
5759e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    }
5760e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
57618db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    float rate;
57628db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    if (params->findFloat("operating-rate", &rate) && rate > 0) {
57638db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        status_t err = setOperatingRate(rate, mIsVideo);
57648db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        if (err != OK) {
57658db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu            ALOGE("Failed to set parameter 'operating-rate' (err %d)", err);
57668db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu            return err;
57678db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        }
57688db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    }
57698db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu
5770a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return OK;
5771a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
5772a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
57736507d14c6d10f93d390de62b9eed267f9b544985Andy McFaddenvoid ACodec::onSignalEndOfInputStream() {
57746507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    sp<AMessage> notify = mNotify->dup();
5775d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatSignaledInputEOS);
57766507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
57776507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    status_t err = mOMX->signalEndOfInputStream(mNode);
57786507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    if (err != OK) {
57796507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        notify->setInt32("err", err);
57806507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    }
57816507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->post();
57826507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden}
57836507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
5784f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onOMXEvent(
5785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventPortSettingsChanged:
5788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
5790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
579131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
5792054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mCodec->mMetaDataBuffersToSubmit = 0;
5793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
5794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
5795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_CommandPortDisable, kPortIndexOutput),
5796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
5797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5798349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                mCodec->freeOutputBuffersNotOwnedByComponent();
5799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
580131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            } else if (data2 == OMX_IndexConfigCommonOutputCrop) {
580231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
5803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
5804ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08x",
5805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->mComponentName.c_str(), data2);
5806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventBufferFlag:
5812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5823f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
5824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ACodec *codec)
5825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5828f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
5829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
5830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput) {
5831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return FREE_BUFFERS;
5832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
5835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
5837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5839f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onMessageReceived(
5840f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
5841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5846349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case kWhatResume:
5847e6eea3a6b6e0cf92287ec1ceb8350f201d17e1acPer Persson        case kWhatSetParameters:
5848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5849349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            if (msg->what() == kWhatResume) {
58503856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
5851349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            }
5852349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
5854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5866f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::OutputPortSettingsChangedState::stateEntered() {
58673856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now handling output port settings change",
5868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mCodec->mComponentName.c_str());
5869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5871f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onOMXEvent(
5872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
5877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
5878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
58793856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now disabled.",
5880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
5881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mCodec->mBuffers[kPortIndexOutput].isEmpty());
5883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mDealer[kPortIndexOutput].clear();
5884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
5886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput),
5887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
5888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5889cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                status_t err;
5890cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                if ((err = mCodec->allocateBuffersOnPort(
5891cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                                kPortIndexOutput)) != OK) {
589229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("Failed to allocate output port buffers after "
5893cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         "port reconfiguration (error 0x%08x)",
5894cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         err);
5895cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
5896251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5897d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
5898755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // This is technically not correct, but appears to be
5899755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the only way to free the component instance.
5900755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // Controlled transitioning from excecuting->idle
5901755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // and idle->loaded seem impossible probably because
5902755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the output port never finishes re-enabling.
5903755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mShutdownInProgress = true;
5904755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mKeepComponentAllocated = false;
5905755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->changeState(mCodec->mLoadedState);
5906cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                }
5907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
5909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
5910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
5911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
591231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
591331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
59143856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now reenabled.",
5915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
5916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5917349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                if (mCodec->mExecutingState->active()) {
5918349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    mCodec->mExecutingState->submitOutputBuffers();
5919349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                }
5920349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mExecutingState);
5922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
5924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
5927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
5931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5936f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
59375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : BaseState(codec),
59385778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mComponentNowIdle(false) {
5939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5941f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
5942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
5948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
5949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
5950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
5956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5969f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::stateEntered() {
59703856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
597131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
59725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mComponentNowIdle = false;
597331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mCodec->mSentFormat = false;
5974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5976f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onOMXEvent(
5977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
5982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
5983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
59845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mComponentNowIdle = true;
59855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            changeStateIfWeOwnAllBuffers();
5987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5991349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
5992349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventBufferFlag:
5993349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
5994349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We're shutting down and don't care about this anymore.
5995349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
5996349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
5997349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
6000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
60020af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
6003f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
60045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
6005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->sendCommand(
6006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded),
6007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
6008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexInput), (status_t)OK);
6010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexOutput), (status_t)OK);
6011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
60120167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown)
60130167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && mCodec->mNativeWindow != NULL) {
6014bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // We push enough 1x1 blank buffers to ensure that one of
6015bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // them has made it to the display.  This allows the OMX
6016bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // component teardown to zero out any protected buffers
6017bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // without the risk of scanning out one of those buffers.
6018bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            mCodec->pushBlankBuffersToNativeWindow();
6019bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
6020bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
6021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mIdleToLoadedState);
6022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6025f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onInputBufferFilled(
6026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
6027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
6028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
6030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6032f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onOutputBufferDrained(
6033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
6034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
6035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
6037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
6040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6041f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
6042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
6043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6045f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
6046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
6047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
6049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
6050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
6052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
6058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
6060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
6061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
6062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
6067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
6071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6073f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToLoadedState::stateEntered() {
60743856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
6075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6077f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onOMXEvent(
6078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
6080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
6081f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
6083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateLoaded);
6084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6085c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->changeState(mCodec->mLoadedState);
6086f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6089f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
6092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6094f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6095f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
6096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6097f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::FlushingState::FlushingState(ACodec *codec)
6098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
6099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6101f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::stateEntered() {
61023856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
6103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
6105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6107f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
6108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
6109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
6111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
6112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
6114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
6118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing this right now.
6120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
6126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
6130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6132f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onOMXEvent(
6133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6134ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGV("[%s] FlushingState onOMXEvent(%u,%d)",
6135ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar            mCodec->mComponentName.c_str(), event, (OMX_S32)data1);
6136d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
6137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
6138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
6139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandFlush);
6141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
6143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(!mFlushComplete[data2]);
6144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mFlushComplete[data2] = true;
6145e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber
6146e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                if (mFlushComplete[kPortIndexInput]
6147e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                        && mFlushComplete[kPortIndexOutput]) {
6148e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                    changeStateIfWeOwnAllBuffers();
6149e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                }
6150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
6151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, OMX_ALL);
6152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexInput]);
6153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexOutput]);
6154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                changeStateIfWeOwnAllBuffers();
6156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
6157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6161349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
6162349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
61631d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec);
6164349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("type", omx_message::EVENT);
6165609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            msg->setInt32("node", mCodec->mNode);
6166349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("event", event);
6167349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data1", data1);
6168349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data2", data2);
6169349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
61703856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
6171349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                 mCodec->mComponentName.c_str());
6172349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6173349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mCodec->deferMessage(msg);
6174349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6175349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
6176349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
6177349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
6180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
6183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6185f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
6186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
6187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
6189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6191f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
6192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
6193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
6195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6197f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
6198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mFlushComplete[kPortIndexInput]
6199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mFlushComplete[kPortIndexOutput]
6200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mCodec->allYourBuffersAreBelongToUs()) {
62017e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // We now own all buffers except possibly those still queued with
62027e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // the native window for rendering. Let's get those back as well.
62037e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
62047e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
6205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
6206d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatFlushCompleted);
6207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->post();
6208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->mPortEOS[kPortIndexInput] =
6210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mPortEOS[kPortIndexOutput] = false;
6211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6212dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber        mCodec->mInputEOSResult = OK;
6213dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
6214f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        if (mCodec->mSkipCutBuffer != NULL) {
6215f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen            mCodec->mSkipCutBuffer->clear();
6216f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        }
6217f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen
6218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mExecutingState);
6219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
6223