ACodec.cpp revision 15ab4996019387f27a48b81cb4774c21502bc0e5
127c174483a8ae9688d5d4897c19074f62c7f1701James Dong/*
227c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Copyright (C) 2010 The Android Open Source Project
327c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
427c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Licensed under the Apache License, Version 2.0 (the "License");
527c174483a8ae9688d5d4897c19074f62c7f1701James Dong * you may not use this file except in compliance with the License.
627c174483a8ae9688d5d4897c19074f62c7f1701James Dong * You may obtain a copy of the License at
727c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
827c174483a8ae9688d5d4897c19074f62c7f1701James Dong *      http://www.apache.org/licenses/LICENSE-2.0
927c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
1027c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Unless required by applicable law or agreed to in writing, software
1127c174483a8ae9688d5d4897c19074f62c7f1701James Dong * distributed under the License is distributed on an "AS IS" BASIS,
1227c174483a8ae9688d5d4897c19074f62c7f1701James Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1327c174483a8ae9688d5d4897c19074f62c7f1701James Dong * See the License for the specific language governing permissions and
1427c174483a8ae9688d5d4897c19074f62c7f1701James Dong * limitations under the License.
1527c174483a8ae9688d5d4897c19074f62c7f1701James Dong */
1627c174483a8ae9688d5d4897c19074f62c7f1701James Dong
17f933441648ef6a71dee783d733aac17b9508b452Andreas Huber//#define LOG_NDEBUG 0
18f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#define LOG_TAG "ACodec"
19f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
20f87e30fe71752dc431d8e8d5682c38271c03265aAndy Hung#ifdef __LP64__
21f87e30fe71752dc431d8e8d5682c38271c03265aAndy Hung#define OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
22f87e30fe71752dc431d8e8d5682c38271c03265aAndy Hung#endif
23f87e30fe71752dc431d8e8d5682c38271c03265aAndy Hung
24609b815a3131d22da38b2f452faa9f89daad4039Andy Hung#include <inttypes.h>
256fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar#include <utils/Trace.h>
266fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar
271de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar#include <gui/Surface.h>
281de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar
29f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/ACodec.h>
30f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <binder/MemoryDealer.h>
32f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/hexdump.h>
34f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ABuffer.h>
35f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ADebug.h>
36f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/AMessage.h>
37a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar#include <media/stagefright/foundation/AUtils.h>
38f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
397cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden#include <media/stagefright/BufferProducerWrapper.h>
40afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber#include <media/stagefright/MediaCodecList.h>
41f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaDefs.h>
42f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/OMXClient.h>
431065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber#include <media/stagefright/OMXCodec.h>
44d291c222357303b9611cab89d0c3b047584ef377Chong Zhang#include <media/stagefright/PersistentSurface.h>
45b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar#include <media/stagefright/SurfaceUtils.h>
463a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber#include <media/hardware/HardwareAPI.h>
473a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
4897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu#include <OMX_AudioExt.h>
494154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev#include <OMX_VideoExt.h>
50f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <OMX_Component.h>
5197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu#include <OMX_IndexExt.h>
52777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim#include <OMX_AsString.h>
53f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
54496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#include "include/avc_utils.h"
55496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
56f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android {
57f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
58251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// OMX errors are directly mapped into status_t range if
59251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// there is no corresponding MediaError status code.
60251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Use the statusFromOMXError(int32_t omxError) function.
61251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung//
62251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Currently this is a direct map.
63251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// See frameworks/native/include/media/openmax/OMX_Core.h
64251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung//
65251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Vendor OMX errors     from 0x90000000 - 0x9000FFFF
66251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Extension OMX errors  from 0x8F000000 - 0x90000000
67251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Standard OMX errors   from 0x80001000 - 0x80001024 (0x80001024 current)
68251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung//
69251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
70251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// returns true if err is a recognized OMX error code.
71251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// as OMX error is OMX_S32, this is an int32_t type
72251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hungstatic inline bool isOMXError(int32_t err) {
73251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    return (ERROR_CODEC_MIN <= err && err <= ERROR_CODEC_MAX);
74251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung}
75251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
76251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// converts an OMX error to a status_t
77251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hungstatic inline status_t statusFromOMXError(int32_t omxError) {
78251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    switch (omxError) {
79251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case OMX_ErrorInvalidComponentName:
80251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case OMX_ErrorComponentNotFound:
81251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return NAME_NOT_FOUND; // can trigger illegal argument error for provided names.
82251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    default:
83251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return isOMXError(omxError) ? omxError : 0; // no translation required
84251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
85251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung}
86251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
87251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// checks and converts status_t to a non-side-effect status_t
88251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hungstatic inline status_t makeNoSideEffectStatus(status_t err) {
89251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    switch (err) {
90251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // the following errors have side effects and may come
91251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // from other code modules. Remap for safety reasons.
92251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case INVALID_OPERATION:
93251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case DEAD_OBJECT:
94251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return UNKNOWN_ERROR;
95251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    default:
96251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return err;
97251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
98251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung}
99251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
100f933441648ef6a71dee783d733aac17b9508b452Andreas Hubertemplate<class T>
101f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic void InitOMXParams(T *params) {
102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nSize = sizeof(T);
103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nVersionMajor = 1;
104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nVersionMinor = 0;
105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nRevision = 0;
106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nStep = 0;
107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
109f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct CodecObserver : public BnOMXObserver {
110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CodecObserver() {}
111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void setNotificationMessage(const sp<AMessage> &msg) {
113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mNotify = msg;
114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // from IOMXObserver
117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onMessage(const omx_message &omx_msg) {
118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> msg = mNotify->dup();
119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->setInt32("type", omx_msg.type);
121609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        msg->setInt32("node", omx_msg.node);
122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        switch (omx_msg.type) {
124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::EVENT:
125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("event", omx_msg.u.event_data.event);
127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("data1", omx_msg.u.event_data.data1);
128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("data2", omx_msg.u.event_data.data2);
129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::EMPTY_BUFFER_DONE:
133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
134609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                msg->setInt32("buffer", omx_msg.u.buffer_data.buffer);
13515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                msg->setInt32("fence_fd", omx_msg.fenceFd);
136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::FILL_BUFFER_DONE:
140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
141609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                msg->setInt32(
142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "buffer", omx_msg.u.extended_buffer_data.buffer);
143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "range_offset",
145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.range_offset);
146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "range_length",
148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.range_length);
149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "flags",
151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.flags);
152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt64(
153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "timestamp",
154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.timestamp);
15515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                msg->setInt32(
15615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                        "fence_fd", omx_msg.fenceFd);
157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            default:
161777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                ALOGE("Unrecognized message type: %d", omx_msg.type);
162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->post();
166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
168f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual ~CodecObserver() {}
170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
171f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> mNotify;
173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(CodecObserver);
175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
179f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::BaseState : public AState {
180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState(ACodec *codec, const sp<AState> &parentState = NULL);
181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
182f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    enum PortMode {
184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        KEEP_BUFFERS,
185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        RESUBMIT_BUFFERS,
186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        FREE_BUFFERS,
187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ACodec *mCodec;
190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void postFillThisBuffer(BufferInfo *info);
201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
202f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXMessage(const sp<AMessage> &msg);
204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
20515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    bool onOMXEmptyBufferDone(IOMX::buffer_id bufferID, int fenceFd);
206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXFillBufferDone(
208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID,
209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            size_t rangeOffset, size_t rangeLength,
210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            OMX_U32 flags,
21115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            int64_t timeUs,
21215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            int fenceFd);
213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void getMoreInputDataIfPossible();
215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(BaseState);
217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
221ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberstruct ACodec::DeathNotifier : public IBinder::DeathRecipient {
222ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    DeathNotifier(const sp<AMessage> &notify)
223ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        : mNotify(notify) {
224ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
225ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
226ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual void binderDied(const wp<IBinder> &) {
227ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mNotify->post();
228ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
229ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
230ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprotected:
231ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual ~DeathNotifier() {}
232ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
233ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprivate:
234ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> mNotify;
235ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
236ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(DeathNotifier);
237ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber};
238ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
239f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::UninitializedState : public ACodec::BaseState {
240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    UninitializedState(ACodec *codec);
241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
242f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
244c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
246f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void onSetup(const sp<AMessage> &msg);
248c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onAllocateComponent(const sp<AMessage> &msg);
249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
250ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<DeathNotifier> mDeathNotifier;
251ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(UninitializedState);
253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
257c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberstruct ACodec::LoadedState : public ACodec::BaseState {
258c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    LoadedState(ACodec *codec);
259c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
260c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprotected:
261c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
262c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
263c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
264c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprivate:
265c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    friend struct ACodec::UninitializedState;
266c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
267c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onConfigureComponent(const sp<AMessage> &msg);
2687cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    void onCreateInputSurface(const sp<AMessage> &msg);
2698f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang    void onSetInputSurface(const sp<AMessage> &msg);
270c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onStart();
271c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onShutdown(bool keepComponentAllocated);
272c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
273d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    status_t setupInputSurface();
274d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
275c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedState);
276c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber};
277c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
278c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
279c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
280f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::LoadedToIdleState : public ACodec::BaseState {
281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    LoadedToIdleState(ACodec *codec);
282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
283f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
288f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t allocateBuffers();
290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedToIdleState);
292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
296f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToExecutingState : public ACodec::BaseState {
297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToExecutingState(ACodec *codec);
298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
299f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
304f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToExecutingState);
306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
310f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingState : public ACodec::BaseState {
311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingState(ACodec *codec);
312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
313054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitRegularOutputBuffers();
314054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitOutputMetaBuffers();
315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void submitOutputBuffers();
316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Submit output buffers to the decoder, submit input buffers to client
318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // to fill with data.
319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void resume();
320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
321349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    // Returns true iff input and output buffers are in play.
322349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool active() const { return mActive; }
323349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
324f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
331f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
332349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool mActive;
333349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingState);
335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
339f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::OutputPortSettingsChangedState : public ACodec::BaseState {
340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OutputPortSettingsChangedState(ACodec *codec);
341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
342f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
349f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(OutputPortSettingsChangedState);
351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
355f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingToIdleState : public ACodec::BaseState {
356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingToIdleState(ACodec *codec);
357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
358f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
367f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool mComponentNowIdle;
3715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingToIdleState);
373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
377f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToLoadedState : public ACodec::BaseState {
378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToLoadedState(ACodec *codec);
379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
380f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
386f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToLoadedState);
388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
392f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::FlushingState : public ACodec::BaseState {
393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    FlushingState(ACodec *codec);
394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
395f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
404f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool mFlushComplete[2];
406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(FlushingState);
410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
41415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarvoid ACodec::BufferInfo::setWriteFence(int fenceFd, const char *dbg) {
41515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (mFenceFd >= 0) {
41615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ALOGW("OVERWRITE OF %s fence %d by write fence %d in %s",
41715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                mIsReadFence ? "read" : "write", mFenceFd, fenceFd, dbg);
41815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
41915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    mFenceFd = fenceFd;
42015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    mIsReadFence = false;
42115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar}
42215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
42315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarvoid ACodec::BufferInfo::setReadFence(int fenceFd, const char *dbg) {
42415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (mFenceFd >= 0) {
42515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ALOGW("OVERWRITE OF %s fence %d by read fence %d in %s",
42615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                mIsReadFence ? "read" : "write", mFenceFd, fenceFd, dbg);
42715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
42815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    mFenceFd = fenceFd;
42915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    mIsReadFence = true;
43015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar}
43115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
43215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarvoid ACodec::BufferInfo::checkWriteFence(const char *dbg) {
43315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (mFenceFd >= 0 && mIsReadFence) {
43415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ALOGD("REUSING read fence %d as write fence in %s", mFenceFd, dbg);
43515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
43615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar}
43715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
43815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarvoid ACodec::BufferInfo::checkReadFence(const char *dbg) {
43915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (mFenceFd >= 0 && !mIsReadFence) {
44015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ALOGD("REUSING write fence %d as read fence in %s", mFenceFd, dbg);
44115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
44215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar}
44315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
44415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar////////////////////////////////////////////////////////////////////////////////
44515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
446f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ACodec()
447afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    : mQuirks(0),
448609b815a3131d22da38b2f452faa9f89daad4039Andy Hung      mNode(0),
4495778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mSentFormat(false),
4508db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu      mIsVideo(false),
451c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber      mIsEncoder(false),
4529806555d3930be43e11106281dee354820ac1c88Andreas Huber      mShutdownInProgress(false),
45354b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar      mExplicitShutdown(false),
4549806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderDelay(0),
4559806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderPadding(0),
456e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang      mRotationDegrees(0),
4579806555d3930be43e11106281dee354820ac1c88Andreas Huber      mChannelMaskPresent(false),
458054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mChannelMask(0),
459054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mDequeueCounter(0),
460054219874873b41f1c815552987c10465c34ba2bLajos Molnar      mInputMetadataType(kMetadataBufferTypeInvalid),
461054219874873b41f1c815552987c10465c34ba2bLajos Molnar      mOutputMetadataType(kMetadataBufferTypeInvalid),
462011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar      mLegacyAdaptiveExperiment(false),
463054219874873b41f1c815552987c10465c34ba2bLajos Molnar      mMetadataBuffersToSubmit(0),
46494ee4b708acfa941581160b267afb79192b1d816Chong Zhang      mRepeatFrameDelayUs(-1ll),
4652c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang      mMaxPtsGapUs(-1ll),
46637b2b389139ed638831e49708c947863eef631efRonghua Wu      mMaxFps(-1),
4672c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang      mTimePerFrameUs(-1ll),
468609b815a3131d22da38b2f452faa9f89daad4039Andy Hung      mTimePerCaptureUs(-1ll),
469ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad      mCreateInputBuffersSuspended(false),
470ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad      mTunneled(false) {
471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mUninitializedState = new UninitializedState(this);
472c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mLoadedState = new LoadedState(this);
473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mLoadedToIdleState = new LoadedToIdleState(this);
474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToExecutingState = new IdleToExecutingState(this);
475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingState = new ExecutingState(this);
476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOutputPortSettingsChangedState =
478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        new OutputPortSettingsChangedState(this);
479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingToIdleState = new ExecutingToIdleState(this);
481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToLoadedState = new IdleToLoadedState(this);
482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushingState = new FlushingState(this);
483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
485dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber    mInputEOSResult = OK;
486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeState(mUninitializedState);
488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
490f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::~ACodec() {
491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
493f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::setNotificationMessage(const sp<AMessage> &msg) {
494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mNotify = msg;
495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
497f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::initiateSetup(const sp<AMessage> &msg) {
498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setWhat(kWhatSetup);
4991d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    msg->setTarget(this);
500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
503a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Hubervoid ACodec::signalSetParameters(const sp<AMessage> &params) {
5041d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetParameters, this);
505a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->setMessage("params", params);
506a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->post();
507a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
508a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5095778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateAllocateComponent(const sp<AMessage> &msg) {
5105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatAllocateComponent);
5111d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    msg->setTarget(this);
5125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
5135778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
5145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5155778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateConfigureComponent(const sp<AMessage> &msg) {
5165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatConfigureComponent);
5171d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    msg->setTarget(this);
5185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
5195778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
5205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5211dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t ACodec::setSurface(const sp<Surface> &surface) {
5221dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetSurface, this);
5231dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    msg->setObject("surface", surface);
5241dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
5251dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    sp<AMessage> response;
5261dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    status_t err = msg->postAndAwaitResponse(&response);
5271dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
5281dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err == OK) {
5291dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        (void)response->findInt32("err", &err);
5301dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
5311dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    return err;
5321dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar}
5331dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
5347cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::initiateCreateInputSurface() {
5351d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatCreateInputSurface, this))->post();
5367cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
5377cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
5388f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhangvoid ACodec::initiateSetInputSurface(
539d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        const sp<PersistentSurface> &surface) {
5408f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang    sp<AMessage> msg = new AMessage(kWhatSetInputSurface, this);
541d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    msg->setObject("input-surface", surface);
542d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    msg->post();
543d291c222357303b9611cab89d0c3b047584ef377Chong Zhang}
544d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5457cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::signalEndOfInputStream() {
5461d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatSignalEndOfInputStream, this))->post();
5477cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
5487cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
5495778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateStart() {
5501d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatStart, this))->post();
5515778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
5525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
553f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalFlush() {
5547a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] signalFlush", mComponentName.c_str());
5551d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatFlush, this))->post();
556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
558f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalResume() {
5591d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatResume, this))->post();
560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
562c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::initiateShutdown(bool keepComponentAllocated) {
5631d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatShutdown, this);
564c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->setInt32("keepComponentAllocated", keepComponentAllocated);
565c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->post();
56630358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar    if (!keepComponentAllocated) {
56730358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        // ensure shutdown completes in 3 seconds
5681d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar        (new AMessage(kWhatReleaseCodecInstance, this))->post(3000000);
56930358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar    }
570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
572496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubervoid ACodec::signalRequestIDRFrame() {
5731d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatRequestIDRFrame, this))->post();
574496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
575496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5764dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
5774dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// Some codecs may return input buffers before having them processed.
5784dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// This causes a halt if we already signaled an EOS on the input
5794dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// port.  For now keep submitting an output buffer if there was an
5804dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// EOS on the input port, but not yet on the output port.
581054219874873b41f1c815552987c10465c34ba2bLajos Molnarvoid ACodec::signalSubmitOutputMetadataBufferIfEOS_workaround() {
5824dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    if (mPortEOS[kPortIndexInput] && !mPortEOS[kPortIndexOutput] &&
583054219874873b41f1c815552987c10465c34ba2bLajos Molnar            mMetadataBuffersToSubmit > 0) {
584054219874873b41f1c815552987c10465c34ba2bLajos Molnar        (new AMessage(kWhatSubmitOutputMetadataBufferIfEOS, this))->post();
5854dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    }
5864dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar}
5874dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
5881dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t ACodec::handleSetSurface(const sp<Surface> &surface) {
5891dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // allow keeping unset surface
5901dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (surface == NULL) {
5911dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        if (mNativeWindow != NULL) {
5921dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            ALOGW("cannot unset a surface");
5931dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            return INVALID_OPERATION;
5941dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
5951dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return OK;
5961dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
5971dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
5981dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // allow keeping unset surface
5991dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mNativeWindow == NULL) {
6001dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGW("component was not configured with a surface");
6011dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return INVALID_OPERATION;
6021dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6031dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
6041dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    ANativeWindow *nativeWindow = surface.get();
6051dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // if we have not yet started the codec, we can simply set the native window
6061dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mBuffers[kPortIndexInput].size() == 0) {
6071dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        mNativeWindow = surface;
6081dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return OK;
6091dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6101dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
6111dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // we do not support changing a tunneled surface after start
6121dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mTunneled) {
6131dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGW("cannot change tunneled surface");
6141dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return INVALID_OPERATION;
6151dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6161dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
6171dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    status_t err = setupNativeWindowSizeFormatAndUsage(nativeWindow);
6181dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != OK) {
6191dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
6201dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6211dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
6221dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // get min undequeued count. We cannot switch to a surface that has a higher
6231dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // undequeued count than we allocated.
6241dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    int minUndequeuedBuffers = 0;
6251dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    err = nativeWindow->query(
6261dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            nativeWindow, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
6271dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            &minUndequeuedBuffers);
6281dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != 0) {
6291dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
6301dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                strerror(-err), -err);
6311dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
6321dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6331dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (minUndequeuedBuffers > (int)mNumUndequeuedBuffers) {
6341dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGE("new surface holds onto more buffers (%d) than planned for (%zu)",
6351dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                minUndequeuedBuffers, mNumUndequeuedBuffers);
6361dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return BAD_VALUE;
6371dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6381dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
6391dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // we cannot change the number of output buffers while OMX is running
6401dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // set up surface to the same count
6411dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    Vector<BufferInfo> &buffers = mBuffers[kPortIndexOutput];
6421dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    ALOGV("setting up surface for %zu buffers", buffers.size());
6431dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
6441dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    err = native_window_set_buffer_count(nativeWindow, buffers.size());
6451dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != 0) {
6461dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
6471dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                -err);
6481dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
6491dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6501dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
651dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    // need to enable allocation when attaching
652dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    surface->getIGraphicBufferProducer()->allowAllocation(true);
653dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar
6541dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // for meta data mode, we move dequeud buffers to the new surface.
6551dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // for non-meta mode, we must move all registered buffers
6561dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    for (size_t i = 0; i < buffers.size(); ++i) {
6571dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        const BufferInfo &info = buffers[i];
6581dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        // skip undequeued buffers for meta data mode
659054219874873b41f1c815552987c10465c34ba2bLajos Molnar        if (storingMetadataInDecodedBuffers()
660011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                && !mLegacyAdaptiveExperiment
6611dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                && info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
6621dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            ALOGV("skipping buffer %p", info.mGraphicBuffer->getNativeBuffer());
6631dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            continue;
6641dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
6651dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGV("attaching buffer %p", info.mGraphicBuffer->getNativeBuffer());
6661dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
6671dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        err = surface->attachBuffer(info.mGraphicBuffer->getNativeBuffer());
6681dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        if (err != OK) {
6691dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            ALOGE("failed to attach buffer %p to the new surface: %s (%d)",
6701dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    info.mGraphicBuffer->getNativeBuffer(),
6711dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    strerror(-err), -err);
6721dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            return err;
6731dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
6741dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6751dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
6761dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // cancel undequeued buffers to new surface
677054219874873b41f1c815552987c10465c34ba2bLajos Molnar    if (!storingMetadataInDecodedBuffers() || mLegacyAdaptiveExperiment) {
6781dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        for (size_t i = 0; i < buffers.size(); ++i) {
67915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            BufferInfo &info = buffers.editItemAt(i);
6801dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
6811dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                ALOGV("canceling buffer %p", info.mGraphicBuffer->getNativeBuffer());
6821dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                err = nativeWindow->cancelBuffer(
68315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                        nativeWindow, info.mGraphicBuffer->getNativeBuffer(), info.mFenceFd);
68415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info.mFenceFd = -1;
6851dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                if (err != OK) {
6861dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    ALOGE("failed to cancel buffer %p to the new surface: %s (%d)",
6871dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                            info.mGraphicBuffer->getNativeBuffer(),
6881dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                            strerror(-err), -err);
6891dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    return err;
6901dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                }
6911dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            }
6921dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
6931dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        // disallow further allocation
6941dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        (void)surface->getIGraphicBufferProducer()->allowAllocation(false);
6951dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6961dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
697484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar    // push blank buffers to previous window if requested
698484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar    if (mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown) {
699484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar        pushBlankBuffersToNativeWindow(mNativeWindow.get());
700484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar    }
701484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar
7021dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    mNativeWindow = nativeWindow;
7031dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    return OK;
7041dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar}
7051dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
706f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mDealer[portIndex] == NULL);
710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mBuffers[portIndex].isEmpty());
711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
714054219874873b41f1c815552987c10465c34ba2bLajos Molnar        if (storingMetadataInDecodedBuffers()) {
715054219874873b41f1c815552987c10465c34ba2bLajos Molnar            err = allocateOutputMetadataBuffers();
716054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
717054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputBuffersFromNativeWindow();
718054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
7195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
7205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
7215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
7225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = portIndex;
723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
7255778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err == OK) {
728054219874873b41f1c815552987c10465c34ba2bLajos Molnar            MetadataBufferType type =
729054219874873b41f1c815552987c10465c34ba2bLajos Molnar                portIndex == kPortIndexOutput ? mOutputMetadataType : mInputMetadataType;
730054219874873b41f1c815552987c10465c34ba2bLajos Molnar            int32_t bufSize = def.nBufferSize;
731054219874873b41f1c815552987c10465c34ba2bLajos Molnar            if (type == kMetadataBufferTypeGrallocSource) {
732054219874873b41f1c815552987c10465c34ba2bLajos Molnar                bufSize = sizeof(VideoGrallocMetadata);
733054219874873b41f1c815552987c10465c34ba2bLajos Molnar            } else if (type == kMetadataBufferTypeANWBuffer) {
734054219874873b41f1c815552987c10465c34ba2bLajos Molnar                bufSize = sizeof(VideoNativeMetadata);
735054219874873b41f1c815552987c10465c34ba2bLajos Molnar            }
736054219874873b41f1c815552987c10465c34ba2bLajos Molnar
737054219874873b41f1c815552987c10465c34ba2bLajos Molnar            // If using gralloc or native source input metadata buffers, allocate largest
738054219874873b41f1c815552987c10465c34ba2bLajos Molnar            // metadata size as we prefer to generate native source metadata, but component
739054219874873b41f1c815552987c10465c34ba2bLajos Molnar            // may require gralloc source.
740054219874873b41f1c815552987c10465c34ba2bLajos Molnar            int32_t allottedSize = bufSize;
741054219874873b41f1c815552987c10465c34ba2bLajos Molnar            if (portIndex == kPortIndexInput && type > 0) {
742054219874873b41f1c815552987c10465c34ba2bLajos Molnar                bufSize = max(sizeof(VideoGrallocMetadata), sizeof(VideoNativeMetadata));
743054219874873b41f1c815552987c10465c34ba2bLajos Molnar            }
744054219874873b41f1c815552987c10465c34ba2bLajos Molnar
745054219874873b41f1c815552987c10465c34ba2bLajos Molnar            ALOGV("[%s] Allocating %u buffers of size %d/%d (from %u using %s) on %s port",
7465778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mComponentName.c_str(),
747054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    def.nBufferCountActual, bufSize, allottedSize, def.nBufferSize, asString(type),
7485778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    portIndex == kPortIndexInput ? "input" : "output");
749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
750054219874873b41f1c815552987c10465c34ba2bLajos Molnar            size_t totalSize = def.nBufferCountActual * bufSize;
7515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
753054219874873b41f1c815552987c10465c34ba2bLajos Molnar            for (OMX_U32 i = 0; i < def.nBufferCountActual && err == OK; ++i) {
754054219874873b41f1c815552987c10465c34ba2bLajos Molnar                sp<IMemory> mem = mDealer[portIndex]->allocate(bufSize);
7555581770ee0dde70e2e9c50533be35e537a5800efChong Zhang                if (mem == NULL || mem->pointer() == NULL) {
756777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return NO_MEMORY;
757777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
759ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                BufferInfo info;
760ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                info.mStatus = BufferInfo::OWNED_BY_US;
76115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info.mFenceFd = -1;
762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
763afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                uint32_t requiresAllocateBufferBit =
764afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                    (portIndex == kPortIndexInput)
765afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        ? OMXCodec::kRequiresAllocateBufferOnInputPorts
766afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        : OMXCodec::kRequiresAllocateBufferOnOutputPorts;
7671065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
768308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                if ((portIndex == kPortIndexInput && (mFlags & kFlagIsSecure))
769054219874873b41f1c815552987c10465c34ba2bLajos Molnar                        || (portIndex == kPortIndexOutput && usingMetadataOnEncoderOutput())) {
770ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    mem.clear();
771ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
772ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    void *ptr;
773ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->allocateBuffer(
774054219874873b41f1c815552987c10465c34ba2bLajos Molnar                            mNode, portIndex, bufSize, &info.mBufferID,
775ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            &ptr);
776ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
777308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    info.mData = new ABuffer(ptr, bufSize);
778ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                } else if (mQuirks & requiresAllocateBufferBit) {
7795778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    err = mOMX->allocateBufferWithBackup(
780054219874873b41f1c815552987c10465c34ba2bLajos Molnar                            mNode, portIndex, mem, &info.mBufferID, allottedSize);
7815778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
782054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    err = mOMX->useBuffer(mNode, portIndex, mem, &info.mBufferID, allottedSize);
783ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                }
784ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
785ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                if (mem != NULL) {
786054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    info.mData = new ABuffer(mem->pointer(), bufSize);
787054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    if (type == kMetadataBufferTypeANWBuffer) {
788054219874873b41f1c815552987c10465c34ba2bLajos Molnar                        ((VideoNativeMetadata *)mem->pointer())->nFenceFd = -1;
789054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    }
7905778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
7911065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
7925778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mBuffers[portIndex].push(info);
7931065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            }
7941065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
7955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
7985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
7995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> notify = mNotify->dup();
802d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatBuffersAllocated);
8035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("portIndex", portIndex);
805eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
806eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    sp<PortDescription> desc = new PortDescription;
807eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
8085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
809eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        const BufferInfo &info = mBuffers[portIndex][i];
8105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
811eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        desc->addBuffer(info.mBufferID, info.mData);
812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
814eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    notify->setObject("portDesc", desc);
8155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->post();
8165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8201dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t ACodec::setupNativeWindowSizeFormatAndUsage(ANativeWindow *nativeWindow /* nonnull */) {
8211dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    OMX_PARAM_PORTDEFINITIONTYPE def;
8221dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    InitOMXParams(&def);
8231dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    def.nPortIndex = kPortIndexOutput;
8241dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
8251dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    status_t err = mOMX->getParameter(
8261dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
8271dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
8281dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != OK) {
8291dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
8301dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
8311dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
8321dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    OMX_U32 usage = 0;
8331dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
8341dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != 0) {
8351dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGW("querying usage flags from OMX IL component failed: %d", err);
8361dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        // XXX: Currently this error is logged, but not fatal.
8371dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        usage = 0;
8381dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
8391dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    int omxUsage = usage;
8401dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
8411dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mFlags & kFlagIsGrallocUsageProtected) {
8421dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        usage |= GRALLOC_USAGE_PROTECTED;
8431dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
8441dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
845b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar    usage |= GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP;
846b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar
8471dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    ALOGV("gralloc usage: %#x(OMX) => %#x(ACodec)", omxUsage, usage);
8481dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    return setNativeWindowSizeFormatAndUsage(
8491dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            nativeWindow,
8501dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            def.format.video.nFrameWidth,
8511dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            def.format.video.nFrameHeight,
8521dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            def.format.video.eColorFormat,
8531dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            mRotationDegrees,
8541dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            usage);
8551dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar}
8561dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
8571dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t ACodec::configureOutputBuffersFromNativeWindow(
8581dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        OMX_U32 *bufferCount, OMX_U32 *bufferSize,
8591dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        OMX_U32 *minUndequeuedBuffers) {
8601dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    OMX_PARAM_PORTDEFINITIONTYPE def;
8611dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    InitOMXParams(&def);
8621dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    def.nPortIndex = kPortIndexOutput;
8631dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
8641dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    status_t err = mOMX->getParameter(
8651dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
8661dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
8671dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err == OK) {
8681dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        err = setupNativeWindowSizeFormatAndUsage(mNativeWindow.get());
8691dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
8701dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != OK) {
8711dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
8721dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
8731dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
874ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // Exits here for tunneled video playback codecs -- i.e. skips native window
875ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // buffer allocation step as this is managed by the tunneled OMX omponent
876ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // itself and explicitly sets def.nBufferCountActual to 0.
877ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    if (mTunneled) {
878ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        ALOGV("Tunneled Playback: skipping native window buffer allocation.");
879ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        def.nBufferCountActual = 0;
880ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        err = mOMX->setParameter(
881ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
882ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
883ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *minUndequeuedBuffers = 0;
884ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *bufferCount = 0;
885ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *bufferSize = 0;
886ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        return err;
887ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    }
888ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
889054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *minUndequeuedBuffers = 0;
890258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    err = mNativeWindow->query(
891258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
892054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (int *)minUndequeuedBuffers);
893258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
894258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    if (err != 0) {
89529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
896258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                strerror(-err), -err);
897258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        return err;
898258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
899258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
900e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // FIXME: assume that surface is controlled by app (native window
901e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // returns the number for the case when surface is not controlled by app)
9021faa41704e0b976e546321effcb09a85767d51baLajos Molnar    // FIXME2: This means that minUndeqeueudBufs can be 1 larger than reported
9031faa41704e0b976e546321effcb09a85767d51baLajos Molnar    // For now, try to allocate 1 more buffer, but don't fail if unsuccessful
904e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar
905e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // Use conservative allocation while also trying to reduce starvation
906e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //
907e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // 1. allocate at least nBufferCountMin + minUndequeuedBuffers - that is the
908e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //    minimum needed for the consumer to be able to work
909e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // 2. try to allocate two (2) additional buffers to reduce starvation from
910e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //    the consumer
9111faa41704e0b976e546321effcb09a85767d51baLajos Molnar    //    plus an extra buffer to account for incorrect minUndequeuedBufs
9121faa41704e0b976e546321effcb09a85767d51baLajos Molnar    for (OMX_U32 extraBuffers = 2 + 1; /* condition inside loop */; extraBuffers--) {
913e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        OMX_U32 newBufferCount =
914e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            def.nBufferCountMin + *minUndequeuedBuffers + extraBuffers;
915258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        def.nBufferCountActual = newBufferCount;
916258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        err = mOMX->setParameter(
917258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
918258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
919e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        if (err == OK) {
920e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            *minUndequeuedBuffers += extraBuffers;
921e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            break;
922e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        }
923e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar
924609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGW("[%s] setting nBufferCountActual to %u failed: %d",
925e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar                mComponentName.c_str(), newBufferCount, err);
926e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        /* exit condition */
927e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        if (extraBuffers == 0) {
928258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            return err;
929258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        }
930258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
931258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffer_count(
933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(), def.nBufferCountActual);
934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
93629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                -err);
938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
941054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferCount = def.nBufferCountActual;
942054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferSize =  def.nBufferSize;
943054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
944054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
945054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
946054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputBuffersFromNativeWindow() {
947054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
948054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
949054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
950054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
951054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
952e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    mNumUndequeuedBuffers = minUndequeuedBuffers;
953054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
954054219874873b41f1c815552987c10465c34ba2bLajos Molnar    if (!storingMetadataInDecodedBuffers()) {
9553298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia        static_cast<Surface*>(mNativeWindow.get())
9563298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia                ->getIGraphicBufferProducer()->allowAllocation(true);
9573298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia    }
9583298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia
959609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Allocating %u buffers from a native window of size %u on "
960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         "output port",
961054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount, bufferSize);
962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Dequeue buffers and send them to OMX
964054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
9658ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev        ANativeWindowBuffer *buf;
96615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        int fenceFd;
96715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf, &fenceFd);
968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
96929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
97474006804065941841883c4b46ee785070164023fJamie Gennis        BufferInfo info;
97574006804065941841883c4b46ee785070164023fJamie Gennis        info.mStatus = BufferInfo::OWNED_BY_US;
97615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info.mFenceFd = fenceFd;
97715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info.mIsReadFence = false;
978054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(NULL /* data */, bufferSize /* capacity */);
97974006804065941841883c4b46ee785070164023fJamie Gennis        info.mGraphicBuffer = graphicBuffer;
98074006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].push(info);
98174006804065941841883c4b46ee785070164023fJamie Gennis
982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferId;
983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &bufferId);
985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
986609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGE("registering GraphicBuffer %u with OMX IL component failed: "
98774006804065941841883c4b46ee785070164023fJamie Gennis                 "%d", i, err);
988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
99174006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
99274006804065941841883c4b46ee785070164023fJamie Gennis
993609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGV("[%s] Registered graphic buffer with ID %u (pointer = %p)",
994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mComponentName.c_str(),
995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             bufferId, graphicBuffer.get());
996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelStart;
999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelEnd;
1000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
1002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // If an error occurred while dequeuing we need to cancel any buffers
1003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // that were dequeued.
1004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelStart = 0;
100574006804065941841883c4b46ee785070164023fJamie Gennis        cancelEnd = mBuffers[kPortIndexOutput].size();
1006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
1007054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // Return the required minimum undequeued buffers to the native window.
1008054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelStart = bufferCount - minUndequeuedBuffers;
1009054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelEnd = bufferCount;
1010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
1013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
10143fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        status_t error = cancelBufferToNativeWindow(info);
10153fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        if (err == 0) {
10163fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia            err = error;
10173fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        }
1018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1020054219874873b41f1c815552987c10465c34ba2bLajos Molnar    if (!storingMetadataInDecodedBuffers()) {
10213298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia        static_cast<Surface*>(mNativeWindow.get())
10223298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia                ->getIGraphicBufferProducer()->allowAllocation(false);
10233298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia    }
10243298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia
1025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
1026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1028054219874873b41f1c815552987c10465c34ba2bLajos Molnarstatus_t ACodec::allocateOutputMetadataBuffers() {
1029054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
1030054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
1031054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
1032054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
1033054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
1034e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    mNumUndequeuedBuffers = minUndequeuedBuffers;
1035054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1036e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar    ALOGV("[%s] Allocating %u meta buffers on output port",
1037e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar         mComponentName.c_str(), bufferCount);
1038e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1039054219874873b41f1c815552987c10465c34ba2bLajos Molnar    size_t bufSize = mOutputMetadataType == kMetadataBufferTypeANWBuffer ?
1040054219874873b41f1c815552987c10465c34ba2bLajos Molnar            sizeof(struct VideoNativeMetadata) : sizeof(struct VideoGrallocMetadata);
1041054219874873b41f1c815552987c10465c34ba2bLajos Molnar    size_t totalSize = bufferCount * bufSize;
1042e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar    mDealer[kPortIndexOutput] = new MemoryDealer(totalSize, "ACodec");
1043e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1044e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar    // Dequeue buffers and send them to OMX
1045e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
1046e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        BufferInfo info;
1047e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        info.mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
104815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info.mFenceFd = -1;
1049e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        info.mGraphicBuffer = NULL;
1050e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        info.mDequeuedAt = mDequeueCounter;
1051e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1052054219874873b41f1c815552987c10465c34ba2bLajos Molnar        sp<IMemory> mem = mDealer[kPortIndexOutput]->allocate(bufSize);
10535581770ee0dde70e2e9c50533be35e537a5800efChong Zhang        if (mem == NULL || mem->pointer() == NULL) {
1054777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return NO_MEMORY;
1055777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        }
1056054219874873b41f1c815552987c10465c34ba2bLajos Molnar        if (mOutputMetadataType == kMetadataBufferTypeANWBuffer) {
1057054219874873b41f1c815552987c10465c34ba2bLajos Molnar            ((VideoNativeMetadata *)mem->pointer())->nFenceFd = -1;
1058054219874873b41f1c815552987c10465c34ba2bLajos Molnar        }
1059e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        info.mData = new ABuffer(mem->pointer(), mem->size());
1060e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1061e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        // we use useBuffer for metadata regardless of quirks
1062e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        err = mOMX->useBuffer(
1063cc7cc67349b7a3f498882087aa42ffc05a2daf11Lajos Molnar                mNode, kPortIndexOutput, mem, &info.mBufferID, mem->size());
1064e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1065e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        mBuffers[kPortIndexOutput].push(info);
1066e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1067e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        ALOGV("[%s] allocated meta buffer with ID %u (pointer = %p)",
1068e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar             mComponentName.c_str(), info.mBufferID, mem->pointer());
1069e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar    }
1070e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1071011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar    if (mLegacyAdaptiveExperiment) {
1072e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        // preallocate and preregister buffers
1073011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        static_cast<Surface *>(mNativeWindow.get())
1074011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                ->getIGraphicBufferProducer()->allowAllocation(true);
1075011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
1076011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        ALOGV("[%s] Allocating %u buffers from a native window of size %u on "
1077011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar             "output port",
1078011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar             mComponentName.c_str(), bufferCount, bufferSize);
1079011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
1080011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        // Dequeue buffers then cancel them all
1081011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        for (OMX_U32 i = 0; i < bufferCount; i++) {
1082e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar            BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
1083e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1084011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            ANativeWindowBuffer *buf;
108515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            int fenceFd;
108615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf, &fenceFd);
1087011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            if (err != 0) {
1088011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
1089011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                break;
1090011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            }
1091011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
1092011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
1093e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar            mOMX->updateGraphicBufferInMeta(
1094e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar                    mNode, kPortIndexOutput, graphicBuffer, info->mBufferID);
1095e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar            info->mStatus = BufferInfo::OWNED_BY_US;
109615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            info->setWriteFence(fenceFd, "allocateOutputMetadataBuffers for legacy");
1097e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar            info->mGraphicBuffer = graphicBuffer;
1098011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        }
1099011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
1100011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        for (OMX_U32 i = 0; i < mBuffers[kPortIndexOutput].size(); i++) {
1101011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
1102011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            status_t error = cancelBufferToNativeWindow(info);
1103011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            if (err == OK) {
1104011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                err = error;
1105011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            }
1106011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        }
1107011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
1108011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        static_cast<Surface*>(mNativeWindow.get())
1109011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                ->getIGraphicBufferProducer()->allowAllocation(false);
1110011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar    }
1111011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
1112054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mMetadataBuffersToSubmit = bufferCount - minUndequeuedBuffers;
1113054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
1114054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
1115054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1116054219874873b41f1c815552987c10465c34ba2bLajos Molnarstatus_t ACodec::submitOutputMetadataBuffer() {
1117054219874873b41f1c815552987c10465c34ba2bLajos Molnar    CHECK(storingMetadataInDecodedBuffers());
1118054219874873b41f1c815552987c10465c34ba2bLajos Molnar    if (mMetadataBuffersToSubmit == 0)
1119054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return OK;
1120054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1121054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *info = dequeueBufferFromNativeWindow();
11220806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (info == NULL) {
1123054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return ERROR_IO;
11240806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
1125054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1126609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] submitting output meta buffer ID %u for graphic buffer %p",
1127054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          mComponentName.c_str(), info->mBufferID, info->mGraphicBuffer.get());
1128054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1129054219874873b41f1c815552987c10465c34ba2bLajos Molnar    --mMetadataBuffersToSubmit;
113015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    info->checkWriteFence("submitOutputMetadataBuffer");
113115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    status_t err = mOMX->fillBuffer(mNode, info->mBufferID, info->mFenceFd);
113215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    info->mFenceFd = -1;
1133777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (err == OK) {
1134777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
1135777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
1136054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1137777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    return err;
1138054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
1139054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
114015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarstatus_t ACodec::waitForFence(int fd, const char *dbg ) {
114115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    status_t res = OK;
114215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (fd >= 0) {
114315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        sp<Fence> fence = new Fence(fd);
114415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        res = fence->wait(IOMX::kFenceTimeoutMs);
114515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ALOGW_IF(res != OK, "FENCE TIMEOUT for %d in %s", fd, dbg);
114615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
114715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    return res;
114815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar}
114915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
11500806340688c937e7b78c2d89db3809274130df4eLajos Molnar// static
11510806340688c937e7b78c2d89db3809274130df4eLajos Molnarconst char *ACodec::_asString(BufferInfo::Status s) {
11520806340688c937e7b78c2d89db3809274130df4eLajos Molnar    switch (s) {
11530806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_US:            return "OUR";
11540806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_COMPONENT:     return "COMPONENT";
11550806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_UPSTREAM:      return "UPSTREAM";
11560806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_DOWNSTREAM:    return "DOWNSTREAM";
11570806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_NATIVE_WINDOW: return "SURFACE";
11580806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::UNRECOGNIZED:           return "UNRECOGNIZED";
11590806340688c937e7b78c2d89db3809274130df4eLajos Molnar        default:                                 return "?";
11600806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
11610806340688c937e7b78c2d89db3809274130df4eLajos Molnar}
11620806340688c937e7b78c2d89db3809274130df4eLajos Molnar
11630806340688c937e7b78c2d89db3809274130df4eLajos Molnarvoid ACodec::dumpBuffers(OMX_U32 portIndex) {
11640806340688c937e7b78c2d89db3809274130df4eLajos Molnar    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
11650806340688c937e7b78c2d89db3809274130df4eLajos Molnar    ALOGI("[%s] %s port has %zu buffers:", mComponentName.c_str(),
11660806340688c937e7b78c2d89db3809274130df4eLajos Molnar            portIndex == kPortIndexInput ? "input" : "output", mBuffers[portIndex].size());
11670806340688c937e7b78c2d89db3809274130df4eLajos Molnar    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
11680806340688c937e7b78c2d89db3809274130df4eLajos Molnar        const BufferInfo &info = mBuffers[portIndex][i];
11690806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGI("  slot %2zu: #%8u %p/%p %s(%d) dequeued:%u",
11700806340688c937e7b78c2d89db3809274130df4eLajos Molnar                i, info.mBufferID, info.mGraphicBuffer.get(),
11710806340688c937e7b78c2d89db3809274130df4eLajos Molnar                info.mGraphicBuffer == NULL ? NULL : info.mGraphicBuffer->getNativeBuffer(),
11720806340688c937e7b78c2d89db3809274130df4eLajos Molnar                _asString(info.mStatus), info.mStatus, info.mDequeuedAt);
11730806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
11740806340688c937e7b78c2d89db3809274130df4eLajos Molnar}
11750806340688c937e7b78c2d89db3809274130df4eLajos Molnar
1176f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
1177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
1178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1179609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Calling cancelBuffer on buffer %u",
1180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mComponentName.c_str(), info->mBufferID);
1181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
118215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    info->checkWriteFence("cancelBufferToNativeWindow");
1183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int err = mNativeWindow->cancelBuffer(
118415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        mNativeWindow.get(), info->mGraphicBuffer.get(), info->mFenceFd);
118515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    info->mFenceFd = -1;
1186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
11873fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia    ALOGW_IF(err != 0, "[%s] can not return buffer %u to native window",
11883fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia            mComponentName.c_str(), info->mBufferID);
11890806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // change ownership even if cancelBuffer fails
1190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
1191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
11923fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia    return err;
1193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1195f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
11968ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev    ANativeWindowBuffer *buf;
1197054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mNativeWindow.get() != NULL);
1198ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
1199ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    if (mTunneled) {
1200ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        ALOGW("dequeueBufferFromNativeWindow() should not be called in tunnel"
1201ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad              " video playback mode mode!");
1202ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        return NULL;
1203ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    }
1204ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
120515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    int fenceFd = -1;
1206dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    do {
120715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        status_t err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf, &fenceFd);
120815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        if (err != 0) {
120915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            ALOGE("dequeueBuffer failed: %s(%d).", asString(err), err);
1210dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            return NULL;
1211dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        }
1212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1213dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        bool stale = false;
1214dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
1215dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
1216dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar
1217dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            if (info->mGraphicBuffer != NULL &&
1218dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                info->mGraphicBuffer->handle == buf->handle) {
1219dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // Since consumers can attach buffers to BufferQueues, it is possible
1220dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // that a known yet stale buffer can return from a surface that we
1221dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // once used.  We can simply ignore this as we have already dequeued
1222dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // this buffer properly.  NOTE: this does not eliminate all cases,
1223dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // e.g. it is possible that we have queued the valid buffer to the
1224dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // NW, and a stale copy of the same buffer gets dequeued - which will
1225dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // be treated as the valid buffer by ACodec.
1226dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                if (info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
1227dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                    ALOGI("dequeued stale buffer %p. discarding", buf);
1228dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                    stale = true;
1229dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                    break;
1230dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                }
1231dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                ALOGV("dequeued buffer %p", info->mGraphicBuffer->getNativeBuffer());
1232dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                info->mStatus = BufferInfo::OWNED_BY_US;
123315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->setWriteFence(fenceFd, "dequeueBufferFromNativeWindow");
1234dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                return info;
1235dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            }
1236dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        }
1237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1238dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // It is also possible to receive a previously unregistered buffer
1239dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // in non-meta mode. These should be treated as stale buffers. The
1240dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // same is possible in meta mode, in which case, it will be treated
1241dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // as a normal buffer, which is not desirable.
1242dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // TODO: fix this.
1243054219874873b41f1c815552987c10465c34ba2bLajos Molnar        if (!stale && (!storingMetadataInDecodedBuffers() || mLegacyAdaptiveExperiment)) {
1244dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            ALOGI("dequeued unrecognized (stale) buffer %p. discarding", buf);
1245dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            stale = true;
1246dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        }
1247dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        if (stale) {
1248dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            // TODO: detach stale buffer, but there is no API yet to do it.
1249dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            buf = NULL;
1250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1251dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    } while (buf == NULL);
1252054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1253dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    // get oldest undequeued buffer
1254dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    BufferInfo *oldest = NULL;
1255dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
1256dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        BufferInfo *info =
1257dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            &mBuffers[kPortIndexOutput].editItemAt(i);
1258054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW &&
1259054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (oldest == NULL ||
1260054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             // avoid potential issues from counter rolling over
1261054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mDequeueCounter - info->mDequeuedAt >
1262054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    mDequeueCounter - oldest->mDequeuedAt)) {
1263054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            oldest = info;
1264054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
1265054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1266054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
12670806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // it is impossible dequeue a buffer when there are no buffers with ANW
12680806340688c937e7b78c2d89db3809274130df4eLajos Molnar    CHECK(oldest != NULL);
12690806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // it is impossible to dequeue an unknown buffer in non-meta mode, as the
12700806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // while loop above does not complete
1271054219874873b41f1c815552987c10465c34ba2bLajos Molnar    CHECK(storingMetadataInDecodedBuffers());
1272054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
12730806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // discard buffer in LRU info and replace with new buffer
12740806340688c937e7b78c2d89db3809274130df4eLajos Molnar    oldest->mGraphicBuffer = new GraphicBuffer(buf, false);
12750806340688c937e7b78c2d89db3809274130df4eLajos Molnar    oldest->mStatus = BufferInfo::OWNED_BY_US;
127615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    oldest->setWriteFence(fenceFd, "dequeueBufferFromNativeWindow for oldest");
1277d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar
12780806340688c937e7b78c2d89db3809274130df4eLajos Molnar    mOMX->updateGraphicBufferInMeta(
12790806340688c937e7b78c2d89db3809274130df4eLajos Molnar            mNode, kPortIndexOutput, oldest->mGraphicBuffer,
12800806340688c937e7b78c2d89db3809274130df4eLajos Molnar            oldest->mBufferID);
1281054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1282054219874873b41f1c815552987c10465c34ba2bLajos Molnar    if (mOutputMetadataType == kMetadataBufferTypeGrallocSource) {
1283054219874873b41f1c815552987c10465c34ba2bLajos Molnar        VideoGrallocMetadata *grallocMeta =
1284054219874873b41f1c815552987c10465c34ba2bLajos Molnar            reinterpret_cast<VideoGrallocMetadata *>(oldest->mData->base());
1285054219874873b41f1c815552987c10465c34ba2bLajos Molnar        ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
1286054219874873b41f1c815552987c10465c34ba2bLajos Molnar                (unsigned)(oldest - &mBuffers[kPortIndexOutput][0]),
1287054219874873b41f1c815552987c10465c34ba2bLajos Molnar                mDequeueCounter - oldest->mDequeuedAt,
1288054219874873b41f1c815552987c10465c34ba2bLajos Molnar                grallocMeta->hHandle,
1289054219874873b41f1c815552987c10465c34ba2bLajos Molnar                oldest->mGraphicBuffer->handle, oldest->mData->base());
1290054219874873b41f1c815552987c10465c34ba2bLajos Molnar    } else if (mOutputMetadataType == kMetadataBufferTypeANWBuffer) {
1291054219874873b41f1c815552987c10465c34ba2bLajos Molnar        VideoNativeMetadata *nativeMeta =
1292054219874873b41f1c815552987c10465c34ba2bLajos Molnar            reinterpret_cast<VideoNativeMetadata *>(oldest->mData->base());
1293054219874873b41f1c815552987c10465c34ba2bLajos Molnar        ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
1294054219874873b41f1c815552987c10465c34ba2bLajos Molnar                (unsigned)(oldest - &mBuffers[kPortIndexOutput][0]),
1295054219874873b41f1c815552987c10465c34ba2bLajos Molnar                mDequeueCounter - oldest->mDequeuedAt,
1296054219874873b41f1c815552987c10465c34ba2bLajos Molnar                nativeMeta->pBuffer,
1297054219874873b41f1c815552987c10465c34ba2bLajos Molnar                oldest->mGraphicBuffer->getNativeBuffer(), oldest->mData->base());
1298054219874873b41f1c815552987c10465c34ba2bLajos Molnar    }
1299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
13000806340688c937e7b78c2d89db3809274130df4eLajos Molnar    return oldest;
1301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1303f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
1304777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    status_t err = OK;
1305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[portIndex].size(); i-- > 0;) {
1306777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        status_t err2 = freeBuffer(portIndex, i);
1307777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        if (err == OK) {
1308777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            err = err2;
1309777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        }
1310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
13120806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // clear mDealer even on an error
1313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDealer[portIndex].clear();
1314777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    return err;
1315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1317349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huberstatus_t ACodec::freeOutputBuffersNotOwnedByComponent() {
1318777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    status_t err = OK;
1319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
1320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
1321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
1322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
13232ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // At this time some buffers may still be with the component
13242ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // or being drained.
13252ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT &&
13262ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar            info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) {
1327777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            status_t err2 = freeBuffer(kPortIndexOutput, i);
1328777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            if (err == OK) {
1329777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                err = err2;
1330777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            }
1331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1334777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    return err;
1335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1337f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
1338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
13390806340688c937e7b78c2d89db3809274130df4eLajos Molnar    status_t err = OK;
1340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
134115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    // there should not be any fences in the metadata
134215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    MetadataBufferType type =
134315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        portIndex == kPortIndexOutput ? mOutputMetadataType : mInputMetadataType;
134415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (type == kMetadataBufferTypeANWBuffer && info->mData != NULL
134515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            && info->mData->size() >= sizeof(VideoNativeMetadata)) {
134615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        int fenceFd = ((VideoNativeMetadata *)info->mData->data())->nFenceFd;
134715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        if (fenceFd >= 0) {
134815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            ALOGW("unreleased fence (%d) in %s metadata buffer %zu",
134915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    fenceFd, portIndex == kPortIndexInput ? "input" : "output", i);
135015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        }
135115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
135215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
13530806340688c937e7b78c2d89db3809274130df4eLajos Molnar    switch (info->mStatus) {
13540806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_US:
13550806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (portIndex == kPortIndexOutput && mNativeWindow != NULL) {
13560806340688c937e7b78c2d89db3809274130df4eLajos Molnar                (void)cancelBufferToNativeWindow(info);
13570806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
13580806340688c937e7b78c2d89db3809274130df4eLajos Molnar            // fall through
1359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
13600806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_NATIVE_WINDOW:
13610806340688c937e7b78c2d89db3809274130df4eLajos Molnar            err = mOMX->freeBuffer(mNode, portIndex, info->mBufferID);
13620806340688c937e7b78c2d89db3809274130df4eLajos Molnar            break;
13630806340688c937e7b78c2d89db3809274130df4eLajos Molnar
13640806340688c937e7b78c2d89db3809274130df4eLajos Molnar        default:
13650806340688c937e7b78c2d89db3809274130df4eLajos Molnar            ALOGE("trying to free buffer not owned by us or ANW (%d)", info->mStatus);
13660806340688c937e7b78c2d89db3809274130df4eLajos Molnar            err = FAILED_TRANSACTION;
13670806340688c937e7b78c2d89db3809274130df4eLajos Molnar            break;
1368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
137015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (info->mFenceFd >= 0) {
137115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ::close(info->mFenceFd);
137215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
137315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
1374777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    // remove buffer even if mOMX->freeBuffer fails
1375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mBuffers[portIndex].removeAt(i);
1376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1377777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    return err;
1378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1380f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::findBufferByID(
13810806340688c937e7b78c2d89db3809274130df4eLajos Molnar        uint32_t portIndex, IOMX::buffer_id bufferID, ssize_t *index) {
1382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
1383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
1384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mBufferID == bufferID) {
1386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (index != NULL) {
1387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                *index = i;
1388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
1390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1393777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    ALOGE("Could not find buffer with ID %u", bufferID);
1394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
1395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
13975778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setComponentRole(
1398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        bool isEncoder, const char *mime) {
1399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    struct MimeToRole {
1400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime;
1401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *decoderRole;
1402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *encoderRole;
1403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
1404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const MimeToRole kMimeToRole[] = {
1406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG,
1407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.mp3", "audio_encoder.mp3" },
14082944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
14092944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp1", "audio_encoder.mp1" },
14102944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
14112944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp2", "audio_encoder.mp2" },
1412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_NB,
1413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrnb", "audio_encoder.amrnb" },
1414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_WB,
1415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrwb", "audio_encoder.amrwb" },
1416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AAC,
1417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.aac", "audio_encoder.aac" },
1418729de186450f78c099637e1fce743fe531862c52Andreas Huber        { MEDIA_MIMETYPE_AUDIO_VORBIS,
1419729de186450f78c099637e1fce743fe531862c52Andreas Huber            "audio_decoder.vorbis", "audio_encoder.vorbis" },
1420bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian        { MEDIA_MIMETYPE_AUDIO_OPUS,
1421bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian            "audio_decoder.opus", "audio_encoder.opus" },
1422c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_MLAW,
1423c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" },
1424c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_ALAW,
1425c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711alaw", "audio_encoder.g711alaw" },
1426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_AVC,
1427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.avc", "video_encoder.avc" },
14282472b1c0d63454e5d90a982bd6c555de6c3127bdRachad        { MEDIA_MIMETYPE_VIDEO_HEVC,
14292472b1c0d63454e5d90a982bd6c555de6c3127bdRachad            "video_decoder.hevc", "video_encoder.hevc" },
1430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_MPEG4,
1431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.mpeg4", "video_encoder.mpeg4" },
1432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_H263,
1433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.h263", "video_encoder.h263" },
143494705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP8,
143594705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp8", "video_encoder.vp8" },
143694705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP9,
143794705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp9", "video_encoder.vp9" },
1438ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        { MEDIA_MIMETYPE_AUDIO_RAW,
1439ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            "audio_decoder.raw", "audio_encoder.raw" },
14402f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        { MEDIA_MIMETYPE_AUDIO_FLAC,
14412f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            "audio_decoder.flac", "audio_encoder.flac" },
1442ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        { MEDIA_MIMETYPE_AUDIO_MSGSM,
1443ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen            "audio_decoder.gsm", "audio_encoder.gsm" },
1444774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu        { MEDIA_MIMETYPE_VIDEO_MPEG2,
1445774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu            "video_decoder.mpeg2", "video_encoder.mpeg2" },
144697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        { MEDIA_MIMETYPE_AUDIO_AC3,
144797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            "audio_decoder.ac3", "audio_encoder.ac3" },
14488a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        { MEDIA_MIMETYPE_AUDIO_EAC3,
14498a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            "audio_decoder.eac3", "audio_encoder.eac3" },
1450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
1451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const size_t kNumMimeToRole =
1453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
1454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    size_t i;
1456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (i = 0; i < kNumMimeToRole; ++i) {
1457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcasecmp(mime, kMimeToRole[i].mime)) {
1458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (i == kNumMimeToRole) {
14635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_UNSUPPORTED;
1464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    const char *role =
1467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        isEncoder ? kMimeToRole[i].encoderRole
1468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                  : kMimeToRole[i].decoderRole;
1469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (role != NULL) {
1471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_PARAM_COMPONENTROLETYPE roleParams;
1472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        InitOMXParams(&roleParams);
1473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        strncpy((char *)roleParams.cRole,
1475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                role, OMX_MAX_STRINGNAME_SIZE - 1);
1476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
1478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->setParameter(
1480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamStandardComponentRole,
1481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &roleParams, sizeof(roleParams));
1482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
14845ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("[%s] Failed to set standard component role '%s'.",
1485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 mComponentName.c_str(), role);
14865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
1488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
14905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
1492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14945778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::configureCodec(
1495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime, const sp<AMessage> &msg) {
14965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t encoder;
14975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("encoder", &encoder)) {
14985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        encoder = false;
14995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1501e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    sp<AMessage> inputFormat = new AMessage();
15024e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    sp<AMessage> outputFormat = mNotify->dup(); // will use this for kWhatOutputFormatChanged
1503e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
15045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mIsEncoder = encoder;
1505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1506054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mInputMetadataType = kMetadataBufferTypeInvalid;
1507054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mOutputMetadataType = kMetadataBufferTypeInvalid;
15088db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu
15095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setComponentRole(encoder /* isEncoder */, mime);
15105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
15125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
15135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitRate = 0;
15162f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    // FLAC encoder doesn't need a bitrate, other encoders do
15172f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
15182f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            && !msg->findInt32("bitrate", &bitRate)) {
15195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
15205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1522d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    int32_t storeMeta;
1523d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (encoder
1524d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && msg->findInt32("store-metadata-in-buffers", &storeMeta)
1525d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && storeMeta != 0) {
1526054219874873b41f1c815552987c10465c34ba2bLajos Molnar        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE, &mInputMetadataType);
1527d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (err != OK) {
1528054219874873b41f1c815552987c10465c34ba2bLajos Molnar            ALOGE("[%s] storeMetaDataInBuffers (input) failed w/ err %d",
1529308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    mComponentName.c_str(), err);
1530d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1531054219874873b41f1c815552987c10465c34ba2bLajos Molnar            return err;
1532054219874873b41f1c815552987c10465c34ba2bLajos Molnar        }
1533054219874873b41f1c815552987c10465c34ba2bLajos Molnar        // For this specific case we could be using camera source even if storeMetaDataInBuffers
1534054219874873b41f1c815552987c10465c34ba2bLajos Molnar        // returns Gralloc source. Pretend that we are; this will force us to use nBufferSize.
1535054219874873b41f1c815552987c10465c34ba2bLajos Molnar        if (mInputMetadataType == kMetadataBufferTypeGrallocSource) {
1536054219874873b41f1c815552987c10465c34ba2bLajos Molnar            mInputMetadataType = kMetadataBufferTypeCameraSource;
1537054219874873b41f1c815552987c10465c34ba2bLajos Molnar        }
1538054219874873b41f1c815552987c10465c34ba2bLajos Molnar    }
1539d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1540308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t prependSPSPPS = 0;
15413a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    if (encoder
15423a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
15433a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && prependSPSPPS != 0) {
15443a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        OMX_INDEXTYPE index;
15453a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        err = mOMX->getExtensionIndex(
15463a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                mNode,
15473a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                "OMX.google.android.index.prependSPSPPSToIDRFrames",
15483a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                &index);
15493a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
15503a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err == OK) {
15513a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            PrependSPSPPSToIDRFramesParams params;
15523a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            InitOMXParams(&params);
15533a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            params.bEnable = OMX_TRUE;
15543a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
15553a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            err = mOMX->setParameter(
15563a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                    mNode, index, &params, sizeof(params));
15573a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
15583a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
15593a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err != OK) {
15603a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            ALOGE("Encoder could not be configured to emit SPS/PPS before "
15613a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                  "IDR frames. (err %d)", err);
15623a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
15633a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            return err;
15643a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
15653a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    }
15663a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
1567308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // Only enable metadata mode on encoder output if encoder can prepend
1568308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // sps/pps to idr frames, since in metadata mode the bitstream is in an
1569308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // opaque handle, to which we don't have access.
1570308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t video = !strncasecmp(mime, "video/", 6);
15718db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    mIsVideo = video;
1572308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (encoder && video) {
1573308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS
1574308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && msg->findInt32("store-metadata-in-buffers-output", &storeMeta)
1575308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && storeMeta != 0);
1576308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1577054219874873b41f1c815552987c10465c34ba2bLajos Molnar        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, enable, &mOutputMetadataType);
1578308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        if (err != OK) {
1579308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            ALOGE("[%s] storeMetaDataInBuffers (output) failed w/ err %d",
1580308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                mComponentName.c_str(), err);
1581308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        }
1582a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
1583a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (!msg->findInt64(
1584a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    "repeat-previous-frame-after",
1585a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    &mRepeatFrameDelayUs)) {
1586a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            mRepeatFrameDelayUs = -1ll;
1587a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
158894ee4b708acfa941581160b267afb79192b1d816Chong Zhang
158994ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (!msg->findInt64("max-pts-gap-to-encoder", &mMaxPtsGapUs)) {
15902c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mMaxPtsGapUs = -1ll;
15912c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
15922c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
159337b2b389139ed638831e49708c947863eef631efRonghua Wu        if (!msg->findFloat("max-fps-to-encoder", &mMaxFps)) {
159437b2b389139ed638831e49708c947863eef631efRonghua Wu            mMaxFps = -1;
159537b2b389139ed638831e49708c947863eef631efRonghua Wu        }
159637b2b389139ed638831e49708c947863eef631efRonghua Wu
15972c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (!msg->findInt64("time-lapse", &mTimePerCaptureUs)) {
15982c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mTimePerCaptureUs = -1ll;
159994ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
160072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
160172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (!msg->findInt32(
160272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    "create-input-buffers-suspended",
160372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    (int32_t*)&mCreateInputBuffersSuspended)) {
160472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mCreateInputBuffersSuspended = false;
160572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
1606308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    }
1607308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
16083a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar    // NOTE: we only use native window for video decoders
1609054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    sp<RefBase> obj;
16100d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    bool haveNativeWindow = msg->findObject("native-window", &obj)
16113a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            && obj != NULL && video && !encoder;
1612011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar    mLegacyAdaptiveExperiment = false;
1613e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if (video && !encoder) {
1614e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        inputFormat->setInt32("adaptive-playback", false);
16151713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang
16161713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        int32_t usageProtected;
16171713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        if (msg->findInt32("protected", &usageProtected) && usageProtected) {
16181713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            if (!haveNativeWindow) {
16191713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang                ALOGE("protected output buffers must be sent to an ANativeWindow");
16201713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang                return PERMISSION_DENIED;
16211713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            }
16221713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            mFlags |= kFlagIsGrallocUsageProtected;
16231713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
16241713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        }
1625e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
16263a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar    if (haveNativeWindow) {
16271de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar        sp<ANativeWindow> nativeWindow =
16281de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar            static_cast<ANativeWindow *>(static_cast<Surface *>(obj.get()));
16295a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
16306597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        // START of temporary support for automatic FRC - THIS WILL BE REMOVED
16316597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        int32_t autoFrc;
16326597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        if (msg->findInt32("auto-frc", &autoFrc)) {
16336597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            bool enabled = autoFrc;
16346597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            OMX_CONFIG_BOOLEANTYPE config;
16356597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            InitOMXParams(&config);
16366597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            config.bEnabled = (OMX_BOOL)enabled;
16376597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            status_t temp = mOMX->setConfig(
16386597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                    mNode, (OMX_INDEXTYPE)OMX_IndexConfigAutoFramerateConversion,
16396597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                    &config, sizeof(config));
16406597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            if (temp == OK) {
16416597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                outputFormat->setInt32("auto-frc", enabled);
16426597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            } else if (enabled) {
16436597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                ALOGI("codec does not support requested auto-frc (err %d)", temp);
16446597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            }
16456597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        }
16466597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        // END of temporary support for automatic FRC
16476597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar
16485a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        int32_t tunneled;
16495a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        if (msg->findInt32("feature-tunneled-playback", &tunneled) &&
16505a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            tunneled != 0) {
16515a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            ALOGI("Configuring TUNNELED video playback.");
1652ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            mTunneled = true;
16535a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
165497827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad            int32_t audioHwSync = 0;
165597827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad            if (!msg->findInt32("audio-hw-sync", &audioHwSync)) {
16565a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGW("No Audio HW Sync provided for video tunnel");
16575a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            }
16585a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            err = configureTunneledVideoPlayback(audioHwSync, nativeWindow);
16595a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (err != OK) {
166097827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad                ALOGE("configureTunneledVideoPlayback(%d,%p) failed!",
16615a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        audioHwSync, nativeWindow.get());
16625a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                return err;
1663fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
1664fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1665d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            int32_t maxWidth = 0, maxHeight = 0;
1666d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            if (msg->findInt32("max-width", &maxWidth) &&
1667d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    msg->findInt32("max-height", &maxHeight)) {
1668d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad
1669d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                err = mOMX->prepareForAdaptivePlayback(
1670d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                        mNode, kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight);
1671d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                if (err != OK) {
1672d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    ALOGW("[%s] prepareForAdaptivePlayback failed w/ err %d",
1673d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                            mComponentName.c_str(), err);
16743a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    // allow failure
16753a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    err = OK;
1676d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                } else {
1677d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("max-width", maxWidth);
1678d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("max-height", maxHeight);
1679d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("adaptive-playback", true);
1680d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                }
1681d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            }
16825a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        } else {
1683ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            ALOGV("Configuring CPU controlled video playback.");
1684ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            mTunneled = false;
1685ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
16863fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // Explicity reset the sideband handle of the window for
16873fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // non-tunneled video in case the window was previously used
16883fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // for a tunneled video playback.
16893fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            err = native_window_set_sideband_stream(nativeWindow.get(), NULL);
16903fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            if (err != OK) {
16913fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad                ALOGE("set_sideband_stream(NULL) failed! (err %d).", err);
16923fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad                return err;
16933fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            }
16943fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad
16955a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            // Always try to enable dynamic output buffers on native surface
16965a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            err = mOMX->storeMetaDataInBuffers(
1697054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    mNode, kPortIndexOutput, OMX_TRUE, &mOutputMetadataType);
16985a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (err != OK) {
16995a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d",
1700fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        mComponentName.c_str(), err);
1701e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
17025a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // if adaptive playback has been requested, try JB fallback
17035a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // NOTE: THIS FALLBACK MECHANISM WILL BE REMOVED DUE TO ITS
17045a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // LARGE MEMORY REQUIREMENT
17055a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
17065a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // we will not do adaptive playback on software accessed
17075a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // surfaces as they never had to respond to changes in the
17085a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // crop window, and we don't trust that they will be able to.
17095a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                int usageBits = 0;
17105a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                bool canDoAdaptivePlayback;
17115a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
17125a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                if (nativeWindow->query(
17135a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        nativeWindow.get(),
17145a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        NATIVE_WINDOW_CONSUMER_USAGE_BITS,
17155a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        &usageBits) != OK) {
17165a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    canDoAdaptivePlayback = false;
17175a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                } else {
17185a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    canDoAdaptivePlayback =
17195a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        (usageBits &
17205a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                                (GRALLOC_USAGE_SW_READ_MASK |
17215a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                                 GRALLOC_USAGE_SW_WRITE_MASK)) == 0;
17225a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                }
17235a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
17245a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                int32_t maxWidth = 0, maxHeight = 0;
17255a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                if (canDoAdaptivePlayback &&
17265a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        msg->findInt32("max-width", &maxWidth) &&
17275a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        msg->findInt32("max-height", &maxHeight)) {
17285a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    ALOGV("[%s] prepareForAdaptivePlayback(%dx%d)",
17295a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mComponentName.c_str(), maxWidth, maxHeight);
17305a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
17315a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    err = mOMX->prepareForAdaptivePlayback(
17325a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mNode, kPortIndexOutput, OMX_TRUE, maxWidth,
17335a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            maxHeight);
17345a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    ALOGW_IF(err != OK,
17355a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            "[%s] prepareForAdaptivePlayback failed w/ err %d",
17365a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mComponentName.c_str(), err);
17375a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
17385a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    if (err == OK) {
17395a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("max-width", maxWidth);
17405a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("max-height", maxHeight);
17415a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("adaptive-playback", true);
17425a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    }
1743e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
17445a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // allow failure
17455a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                err = OK;
17465a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            } else {
17475a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGV("[%s] storeMetaDataInBuffers succeeded",
17485a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        mComponentName.c_str());
1749054219874873b41f1c815552987c10465c34ba2bLajos Molnar                CHECK(storingMetadataInDecodedBuffers());
1750011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                mLegacyAdaptiveExperiment = ADebug::isExperimentEnabled(
1751011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                        "legacy-adaptive", !msg->contains("no-experiments"));
1752011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
17535a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                inputFormat->setInt32("adaptive-playback", true);
1754fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
17550167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber
17565a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            int32_t push;
17575a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (msg->findInt32("push-blank-buffers-on-shutdown", &push)
17585a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    && push != 0) {
17595a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
17605a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            }
17610167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        }
1762e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang
1763e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        int32_t rotationDegrees;
1764e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        if (msg->findInt32("rotation-degrees", &rotationDegrees)) {
1765e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            mRotationDegrees = rotationDegrees;
1766e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        } else {
1767e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            mRotationDegrees = 0;
1768e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        }
1769054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1770054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1771308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (video) {
17723a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // determine need for software renderer
17733a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        bool usingSwRenderer = false;
17743a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (haveNativeWindow && mComponentName.startsWith("OMX.google.")) {
17753a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            usingSwRenderer = true;
17763a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            haveNativeWindow = false;
17773a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
17783a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
17795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (encoder) {
17805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupVideoEncoder(mime, msg);
17815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
17820d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            err = setupVideoDecoder(mime, msg, haveNativeWindow);
17835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17843a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
17853a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (err != OK) {
17863a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            return err;
17873a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
17883a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
17893a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (haveNativeWindow) {
17901de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar            mNativeWindow = static_cast<Surface *>(obj.get());
17913a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
17923a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
17933a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // initialize native window now to get actual output format
17943a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // TODO: this is needed for some encoders even though they don't use native window
1795777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        err = initNativeWindow();
1796777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        if (err != OK) {
1797777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return err;
1798777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        }
17993a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
18003a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // fallback for devices that do not handle flex-YUV for native buffers
18013a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (haveNativeWindow) {
18023a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            int32_t requestedColorFormat = OMX_COLOR_FormatUnused;
18033a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            if (msg->findInt32("color-format", &requestedColorFormat) &&
18043a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    requestedColorFormat == OMX_COLOR_FormatYUV420Flexible) {
1805777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                status_t err = getPortFormat(kPortIndexOutput, outputFormat);
1806777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (err != OK) {
1807777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return err;
1808777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
18093a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                int32_t colorFormat = OMX_COLOR_FormatUnused;
18103a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                OMX_U32 flexibleEquivalent = OMX_COLOR_FormatUnused;
1811777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (!outputFormat->findInt32("color-format", &colorFormat)) {
1812777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGE("ouptut port did not have a color format (wrong domain?)");
1813777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return BAD_VALUE;
1814777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
18153a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                ALOGD("[%s] Requested output format %#x and got %#x.",
18163a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        mComponentName.c_str(), requestedColorFormat, colorFormat);
18173a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                if (!isFlexibleColorFormat(
18183a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                                mOMX, mNode, colorFormat, haveNativeWindow, &flexibleEquivalent)
18193a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        || flexibleEquivalent != (OMX_U32)requestedColorFormat) {
18203a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    // device did not handle flex-YUV request for native window, fall back
18213a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    // to SW renderer
18223a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    ALOGI("[%s] Falling back to software renderer", mComponentName.c_str());
18233a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    mNativeWindow.clear();
18243a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    haveNativeWindow = false;
18253a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    usingSwRenderer = true;
1826054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    if (storingMetadataInDecodedBuffers()) {
1827054219874873b41f1c815552987c10465c34ba2bLajos Molnar                        err = mOMX->storeMetaDataInBuffers(
1828054219874873b41f1c815552987c10465c34ba2bLajos Molnar                                mNode, kPortIndexOutput, OMX_FALSE, &mOutputMetadataType);
1829054219874873b41f1c815552987c10465c34ba2bLajos Molnar                        mOutputMetadataType = kMetadataBufferTypeInvalid; // just in case
18303a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        // TODO: implement adaptive-playback support for bytebuffer mode.
18313a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        // This is done by SW codecs, but most HW codecs don't support it.
18323a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        inputFormat->setInt32("adaptive-playback", false);
18333a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
18343a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    if (err == OK) {
18353a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        err = mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
18363a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
18373a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    if (mFlags & kFlagIsGrallocUsageProtected) {
18383a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        // fallback is not supported for protected playback
18393a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        err = PERMISSION_DENIED;
18403a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    } else if (err == OK) {
18413a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        err = setupVideoDecoder(mime, msg, false);
18423a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
18433a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                }
18443a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            }
18453a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
18463a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
18473a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (usingSwRenderer) {
18483a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            outputFormat->setInt32("using-sw-renderer", 1);
18493a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
185042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
185142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        int32_t numChannels, sampleRate;
185242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        if (!msg->findInt32("channel-count", &numChannels)
185342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
185442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // Since we did not always check for these, leave them optional
185542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // and have the decoder figure it all out.
185642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = OK;
185742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        } else {
185842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = setupRawAudioFormat(
185942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    encoder ? kPortIndexInput : kPortIndexOutput,
186042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    sampleRate,
186142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    numChannels);
186242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        }
1863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
1864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t numChannels, sampleRate;
18655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)
18665778822d86b0337407514b9372562b86edfa91cdAndreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
18675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
18685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
1869aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            int32_t isADTS, aacProfile;
1870b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            int32_t sbrMode;
18718045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            int32_t maxOutputChannelCount;
18722965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            int32_t pcmLimiterEnable;
18738045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            drcParams_t drc;
1874ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            if (!msg->findInt32("is-adts", &isADTS)) {
1875ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                isADTS = 0;
1876ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
1877aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (!msg->findInt32("aac-profile", &aacProfile)) {
1878aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                aacProfile = OMX_AUDIO_AACObjectNull;
1879aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
1880b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            if (!msg->findInt32("aac-sbr-mode", &sbrMode)) {
1881b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                sbrMode = -1;
1882b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            }
1883ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
18848045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-max-output-channel_count", &maxOutputChannelCount)) {
18858045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                maxOutputChannelCount = -1;
18868045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
18872965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            if (!msg->findInt32("aac-pcm-limiter-enable", &pcmLimiterEnable)) {
18882965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                // value is unknown
18892965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                pcmLimiterEnable = -1;
18902965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            }
18918045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-encoded-target-level", &drc.encodedTargetLevel)) {
18928045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
18938045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.encodedTargetLevel = -1;
18948045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
18958045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-cut-level", &drc.drcCut)) {
18968045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
18978045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.drcCut = -1;
18988045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
18998045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-boost-level", &drc.drcBoost)) {
19008045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
19018045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.drcBoost = -1;
19028045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
19038045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-heavy-compression", &drc.heavyCompression)) {
19048045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
19058045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.heavyCompression = -1;
19068045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
19078045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-target-ref-level", &drc.targetRefLevel)) {
19088045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
19098045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.targetRefLevel = -1;
19108045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
19118045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi
1912ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            err = setupAACCodec(
19134471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    encoder, numChannels, sampleRate, bitRate, aacProfile,
19142965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                    isADTS != 0, sbrMode, maxOutputChannelCount, drc,
19152965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                    pcmLimiterEnable);
19165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
1917729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
19185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
1919729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
19205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
1921729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
1922729de186450f78c099637e1fce743fe531862c52Andreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
1923729de186450f78c099637e1fce743fe531862c52Andreas Huber        // These are PCM-like formats with a fixed sample rate but
1924729de186450f78c099637e1fce743fe531862c52Andreas Huber        // a variable number of channels.
1925729de186450f78c099637e1fce743fe531862c52Andreas Huber
1926729de186450f78c099637e1fce743fe531862c52Andreas Huber        int32_t numChannels;
19275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)) {
19285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
19295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
193017c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            int32_t sampleRate;
193117c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            if (!msg->findInt32("sample-rate", &sampleRate)) {
193217c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen                sampleRate = 8000;
193317c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            }
193417c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            err = setupG711Codec(encoder, sampleRate, numChannels);
19355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19362f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
1937ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        int32_t numChannels = 0, sampleRate = 0, compressionLevel = -1;
19382f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (encoder &&
19392f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                (!msg->findInt32("channel-count", &numChannels)
19402f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                        || !msg->findInt32("sample-rate", &sampleRate))) {
19412f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("missing channel count or sample rate for FLAC encoder");
19422f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            err = INVALID_OPERATION;
19432f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        } else {
19442f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            if (encoder) {
1945516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                if (!msg->findInt32(
1946cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                            "complexity", &compressionLevel) &&
1947cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                    !msg->findInt32(
1948516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                            "flac-compression-level", &compressionLevel)) {
1949cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                    compressionLevel = 5; // default FLAC compression level
19502f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel < 0) {
1951516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1952516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 0",
1953516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
19542f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 0;
19552f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel > 8) {
1956516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1957516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 8",
1958516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
19592f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 8;
19602f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                }
19612f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            }
1962516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            err = setupFlacCodec(
1963516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    encoder, numChannels, sampleRate, compressionLevel);
19642f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
1965ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
1966ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        int32_t numChannels, sampleRate;
1967ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        if (encoder
1968ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("channel-count", &numChannels)
1969ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
1970ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = INVALID_OPERATION;
1971ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        } else {
1972ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
1973ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        }
197497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AC3)) {
197597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t numChannels;
197697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t sampleRate;
197797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        if (!msg->findInt32("channel-count", &numChannels)
197897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                || !msg->findInt32("sample-rate", &sampleRate)) {
197997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = INVALID_OPERATION;
198097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        } else {
198197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = setupAC3Codec(encoder, numChannels, sampleRate);
198297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        }
19838a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_EAC3)) {
19848a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        int32_t numChannels;
19858a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        int32_t sampleRate;
19868a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        if (!msg->findInt32("channel-count", &numChannels)
19878a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                || !msg->findInt32("sample-rate", &sampleRate)) {
19888a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            err = INVALID_OPERATION;
19898a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        } else {
19908a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            err = setupEAC3Codec(encoder, numChannels, sampleRate);
19918a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        }
19925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1993729de186450f78c099637e1fce743fe531862c52Andreas Huber
19944471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    if (err != OK) {
19954471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber        return err;
19964471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    }
19974471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber
19988b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
19998b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderDelay = 0;
20008b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
20019806555d3930be43e11106281dee354820ac1c88Andreas Huber
20028b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
20038b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderPadding = 0;
20048b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
20058b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen
20069806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (msg->findInt32("channel-mask", &mChannelMask)) {
20079806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = true;
20089806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else {
20099806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = false;
20109806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
20119806555d3930be43e11106281dee354820ac1c88Andreas Huber
2012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t maxInputSize;
2013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (msg->findInt32("max-input-size", &maxInputSize)) {
20145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
2015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
20165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
2017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
20185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20198b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    int32_t priority;
20208b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    if (msg->findInt32("priority", &priority)) {
20218b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu        err = setPriority(priority);
20228b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    }
20238b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu
2024ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    int32_t rateInt = -1;
2025ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    float rateFloat = -1;
2026ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (!msg->findFloat("operating-rate", &rateFloat)) {
2027ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        msg->findInt32("operating-rate", &rateInt);
2028ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        rateFloat = (float)rateInt;  // 16MHz (FLINTMAX) is OK for upper bound.
2029ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
2030ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (rateFloat > 0) {
2031ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        err = setOperatingRate(rateFloat, video);
2032ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
2033ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu
20344e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    mBaseOutputFormat = outputFormat;
20354e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar
2036777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    err = getPortFormat(kPortIndexInput, inputFormat);
2037777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (err == OK) {
2038777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        err = getPortFormat(kPortIndexOutput, outputFormat);
2039777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        if (err == OK) {
2040777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            mInputFormat = inputFormat;
2041777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            mOutputFormat = outputFormat;
2042777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        }
2043777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
20445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
2045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
20478b806ea894ca098366629458bfdd1df4866afcdfRonghua Wustatus_t ACodec::setPriority(int32_t priority) {
20488b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    if (priority < 0) {
20498b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu        return BAD_VALUE;
20508b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    }
20518b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    OMX_PARAM_U32TYPE config;
20528b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    InitOMXParams(&config);
20538b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    config.nU32 = (OMX_U32)priority;
20548b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    status_t temp = mOMX->setConfig(
20558b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu            mNode, (OMX_INDEXTYPE)OMX_IndexConfigPriority,
20568b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu            &config, sizeof(config));
20578b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    if (temp != OK) {
20588b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu        ALOGI("codec does not support config priority (err %d)", temp);
20598b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    }
20608b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    return OK;
20618b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu}
20628b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu
2063ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wustatus_t ACodec::setOperatingRate(float rateFloat, bool isVideo) {
2064ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (rateFloat < 0) {
2065ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        return BAD_VALUE;
2066ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
2067ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    OMX_U32 rate;
2068ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (isVideo) {
2069ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        if (rateFloat > 65535) {
2070ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            return BAD_VALUE;
2071ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        }
2072ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        rate = (OMX_U32)(rateFloat * 65536.0f + 0.5f);
2073ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    } else {
2074ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        if (rateFloat > UINT_MAX) {
2075ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            return BAD_VALUE;
2076ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        }
2077ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        rate = (OMX_U32)(rateFloat);
2078ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
2079ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    OMX_PARAM_U32TYPE config;
2080ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    InitOMXParams(&config);
2081ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    config.nU32 = rate;
2082ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    status_t err = mOMX->setConfig(
2083ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            mNode, (OMX_INDEXTYPE)OMX_IndexConfigOperatingRate,
2084ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            &config, sizeof(config));
2085ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (err != OK) {
2086ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        ALOGI("codec does not support config operating rate (err %d)", err);
2087ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
2088ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    return OK;
2089ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu}
2090ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu
2091f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
2092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
2093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
2094f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
2095f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
2097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (def.nBufferSize >= size) {
2104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
2105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nBufferSize = size;
2108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
2110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->getParameter(
2117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2123777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (def.nBufferSize < size) {
2124777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("failed to set min buffer size to %zu (is still %u)", size, def.nBufferSize);
2125777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return FAILED_TRANSACTION;
2126777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
2127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
21315778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::selectAudioPortFormat(
21325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
21335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_AUDIO_PARAM_PORTFORMATTYPE format;
21345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&format);
21355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    format.nPortIndex = portIndex;
21375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (OMX_U32 index = 0;; ++index) {
21385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        format.nIndex = index;
21395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
21415778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioPortFormat,
21425778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &format, sizeof(format));
21435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
21455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
21465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (format.eEncoding == desiredFormat) {
21495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
21505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
21545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format));
21555778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
21565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21575778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAACCodec(
2158aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        bool encoder, int32_t numChannels, int32_t sampleRate,
21598045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        int32_t bitRate, int32_t aacProfile, bool isADTS, int32_t sbrMode,
21602965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang        int32_t maxOutputChannelCount, const drcParams_t& drc,
21612965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang        int32_t pcmLimiterEnable) {
2162ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (encoder && isADTS) {
2163ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return -EINVAL;
2164ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
2165ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
21665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setupRawAudioFormat(
21675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
21685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sampleRate,
21695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            numChannels);
21705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (encoder) {
21765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
21775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
21795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
21805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
21835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
21845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = kPortIndexOutput;
21855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
21875778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
21885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
21905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
21915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.bFlagErrorConcealment = OMX_TRUE;
21945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
21955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
21975778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
21985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
22005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
22015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
22045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&profile);
22055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nPortIndex = kPortIndexOutput;
22065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
22085778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
22095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
22115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
22125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nChannels = numChannels;
22155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eChannelMode =
22175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (numChannels == 1)
22185778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
22195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nSampleRate = sampleRate;
22215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nBitRate = bitRate;
22225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAudioBandWidth = 0;
22235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nFrameLength = 0;
22245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACtools = OMX_AUDIO_AACToolAll;
22255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACERtools = OMX_AUDIO_AACERNone;
2226aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
22275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
2228b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        switch (sbrMode) {
2229b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 0:
2230b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // disable sbr
2231b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
2232b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
2233b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2234b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 1:
2235b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable single-rate sbr
2236b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
2237b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
2238b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2239b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 2:
2240b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable dual-rate sbr
2241b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
2242b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
2243b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2244b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case -1:
2245b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable both modes -> the codec will decide which mode should be used
2246b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
2247b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
2248b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2249b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        default:
2250b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // unsupported sbr mode
2251b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            return BAD_VALUE;
2252b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        }
2253b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi
22545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
22565778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
22575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
22595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
22605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_AUDIO_PARAM_AACPROFILETYPE profile;
2266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&profile);
2267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nPortIndex = kPortIndexInput;
2268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
22695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
2270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
2271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nChannels = numChannels;
2277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nSampleRate = sampleRate;
2278ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2279ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    profile.eAACStreamFormat =
2280ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        isADTS
2281ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            ? OMX_AUDIO_AACStreamFormatMP4ADTS
2282ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            : OMX_AUDIO_AACStreamFormatMP4FF;
2283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
22848045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    OMX_AUDIO_PARAM_ANDROID_AACPRESENTATIONTYPE presentation;
22858045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nMaxOutputChannels = maxOutputChannelCount;
22868045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nDrcCut = drc.drcCut;
22878045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nDrcBoost = drc.drcBoost;
22888045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nHeavyCompression = drc.heavyCompression;
22898045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nTargetReferenceLevel = drc.targetRefLevel;
22908045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nEncodedTargetLevel = drc.encodedTargetLevel;
22912965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang    presentation.nPCMLimiterEnable = pcmLimiterEnable;
22928045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi
22938045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    status_t res = mOMX->setParameter(mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
22948045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    if (res == OK) {
22958045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        // optional parameters, will not cause configuration failure
22968045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        mOMX->setParameter(mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAacPresentation,
22978045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                &presentation, sizeof(presentation));
22988045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    } else {
22998045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        ALOGW("did not set AudioAndroidAacPresentation due to error %d when setting AudioAac", res);
23008045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    }
23018045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    return res;
23025778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
2303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
230497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryustatus_t ACodec::setupAC3Codec(
230597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        bool encoder, int32_t numChannels, int32_t sampleRate) {
230697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    status_t err = setupRawAudioFormat(
230797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
230897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
230997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
231097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
231197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
231297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
231397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (encoder) {
231497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        ALOGW("AC3 encoding is not supported.");
231597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return INVALID_OPERATION;
231697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
231797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
231897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    OMX_AUDIO_PARAM_ANDROID_AC3TYPE def;
231997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    InitOMXParams(&def);
232097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nPortIndex = kPortIndexInput;
232197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
232297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    err = mOMX->getParameter(
232397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
232497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
232597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
232697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
232797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
232897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
232997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
233097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
233197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
233297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nChannels = numChannels;
233397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nSampleRate = sampleRate;
233497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
233597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    return mOMX->setParameter(
233697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
233797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
233897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
233997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
234097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu}
234197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
23428a4728966dc9c78e21c3c93a927707e93c05e5e0Rachadstatus_t ACodec::setupEAC3Codec(
23438a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        bool encoder, int32_t numChannels, int32_t sampleRate) {
23448a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    status_t err = setupRawAudioFormat(
23458a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
23468a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
23478a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (err != OK) {
23488a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return err;
23498a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
23508a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
23518a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (encoder) {
23528a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        ALOGW("EAC3 encoding is not supported.");
23538a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return INVALID_OPERATION;
23548a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
23558a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
23568a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    OMX_AUDIO_PARAM_ANDROID_EAC3TYPE def;
23578a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    InitOMXParams(&def);
23588a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nPortIndex = kPortIndexInput;
23598a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
23608a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    err = mOMX->getParameter(
23618a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            mNode,
23628a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
23638a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            &def,
23648a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            sizeof(def));
23658a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
23668a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (err != OK) {
23678a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return err;
23688a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
23698a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
23708a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nChannels = numChannels;
23718a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nSampleRate = sampleRate;
23728a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
23738a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    return mOMX->setParameter(
23748a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            mNode,
23758a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
23768a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            &def,
23778a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            sizeof(def));
23788a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad}
23798a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
23805778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
23815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        bool isAMRWB, int32_t bps) {
23825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (isAMRWB) {
23835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 6600) {
23845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB0;
23855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 8850) {
23865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB1;
23875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 12650) {
23885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB2;
23895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 14250) {
23905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB3;
23915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 15850) {
23925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB4;
23935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 18250) {
23945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB5;
23955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 19850) {
23965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB6;
23975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 23050) {
23985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB7;
23995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
24005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 23850 bps
24025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeWB8;
24035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {  // AMRNB
24045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 4750) {
24055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB0;
24065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5150) {
24075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB1;
24085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5900) {
24095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB2;
24105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 6700) {
24115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB3;
24125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7400) {
24135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB4;
24145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7950) {
24155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB5;
24165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 10200) {
24175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB6;
24185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
24195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 12200 bps
24215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeNB7;
24225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
24255778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
2426729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_AMRTYPE def;
2427729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
24285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
2429729de186450f78c099637e1fce743fe531862c52Andreas Huber
2430729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err =
2431729de186450f78c099637e1fce743fe531862c52Andreas Huber        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
2432729de186450f78c099637e1fce743fe531862c52Andreas Huber
2433729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2434729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2435729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2436729de186450f78c099637e1fce743fe531862c52Andreas Huber
2437729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
24385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
24395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
24415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
2442729de186450f78c099637e1fce743fe531862c52Andreas Huber
24435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
24445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
24455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2446729de186450f78c099637e1fce743fe531862c52Andreas Huber
24475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupRawAudioFormat(
24485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
24495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            isWAMR ? 16000 : 8000 /* sampleRate */,
24505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            1 /* numChannels */);
2451729de186450f78c099637e1fce743fe531862c52Andreas Huber}
2452729de186450f78c099637e1fce743fe531862c52Andreas Huber
245317c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissenstatus_t ACodec::setupG711Codec(bool encoder, int32_t sampleRate, int32_t numChannels) {
2454777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (encoder) {
2455777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return INVALID_OPERATION;
2456777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
24575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2458729de186450f78c099637e1fce743fe531862c52Andreas Huber    return setupRawAudioFormat(
245917c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            kPortIndexInput, sampleRate, numChannels);
2460729de186450f78c099637e1fce743fe531862c52Andreas Huber}
2461729de186450f78c099637e1fce743fe531862c52Andreas Huber
24622f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivistatus_t ACodec::setupFlacCodec(
24632f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
24642f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
24652f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder) {
24662f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        OMX_AUDIO_PARAM_FLACTYPE def;
24672f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        InitOMXParams(&def);
24682f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nPortIndex = kPortIndexOutput;
24692f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
24702f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        // configure compression level
24712f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        status_t err = mOMX->getParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
24722f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
24732f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
24742f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
24752f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
24762f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nCompressionLevel = compressionLevel;
24772f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        err = mOMX->setParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
24782f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
24792f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
24802f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
24812f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
24822f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
24832f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
24842f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    return setupRawAudioFormat(
24852f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            encoder ? kPortIndexInput : kPortIndexOutput,
24862f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            sampleRate,
24872f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            numChannels);
24882f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi}
24892f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
2490729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t ACodec::setupRawAudioFormat(
2491729de186450f78c099637e1fce743fe531862c52Andreas Huber        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
2492729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
2493729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
2494729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.nPortIndex = portIndex;
2495729de186450f78c099637e1fce743fe531862c52Andreas Huber
2496729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err = mOMX->getParameter(
2497729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2498729de186450f78c099637e1fce743fe531862c52Andreas Huber
2499729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2500729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2501729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2502729de186450f78c099637e1fce743fe531862c52Andreas Huber
2503729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
2504729de186450f78c099637e1fce743fe531862c52Andreas Huber
2505729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->setParameter(
2506729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2507729de186450f78c099637e1fce743fe531862c52Andreas Huber
2508729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2509729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2510729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2511729de186450f78c099637e1fce743fe531862c52Andreas Huber
2512729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
2513729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&pcmParams);
2514729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nPortIndex = portIndex;
2515729de186450f78c099637e1fce743fe531862c52Andreas Huber
2516729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->getParameter(
2517729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
2518729de186450f78c099637e1fce743fe531862c52Andreas Huber
2519729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2520729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2521729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2522729de186450f78c099637e1fce743fe531862c52Andreas Huber
2523729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nChannels = numChannels;
2524729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.eNumData = OMX_NumericalDataSigned;
2525729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.bInterleaved = OMX_TRUE;
2526729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nBitPerSample = 16;
2527729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nSamplingRate = sampleRate;
2528729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
2529729de186450f78c099637e1fce743fe531862c52Andreas Huber
2530c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber    if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
2531c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber        return OMX_ErrorNone;
2532729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2533729de186450f78c099637e1fce743fe531862c52Andreas Huber
2534729de186450f78c099637e1fce743fe531862c52Andreas Huber    return mOMX->setParameter(
2535729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
2536729de186450f78c099637e1fce743fe531862c52Andreas Huber}
2537729de186450f78c099637e1fce743fe531862c52Andreas Huber
25385a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachadstatus_t ACodec::configureTunneledVideoPlayback(
253997827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad        int32_t audioHwSync, const sp<ANativeWindow> &nativeWindow) {
25405a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    native_handle_t* sidebandHandle;
25415a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
25425a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    status_t err = mOMX->configureVideoTunnelMode(
25435a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            mNode, kPortIndexOutput, OMX_TRUE, audioHwSync, &sidebandHandle);
25445a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    if (err != OK) {
25455a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        ALOGE("configureVideoTunnelMode failed! (err %d).", err);
25465a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        return err;
25475a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    }
25485a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
25495a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    err = native_window_set_sideband_stream(nativeWindow.get(), sidebandHandle);
25505a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    if (err != OK) {
25515a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        ALOGE("native_window_set_sideband_stream(%p) failed! (err %d).",
25525a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                sidebandHandle, err);
25535a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        return err;
25545a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    }
25555a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
25565a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    return OK;
25575a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad}
25585a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
2559f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoPortFormatType(
2560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
2561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_VIDEO_CODINGTYPE compressionFormat,
25620d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        OMX_COLOR_FORMATTYPE colorFormat,
25630d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        bool usingNativeBuffers) {
2564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
2565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
2566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = portIndex;
2567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
2568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool found = false;
2569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 index = 0;
2571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (;;) {
2572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        format.nIndex = index;
2573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->getParameter(
2574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamVideoPortFormat,
2575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &format, sizeof(format));
2576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
2578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return err;
2579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2581229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        // substitute back flexible color format to codec supported format
2582229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        OMX_U32 flexibleEquivalent;
25830d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (compressionFormat == OMX_VIDEO_CodingUnused
25840d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && isFlexibleColorFormat(
25850d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        mOMX, mNode, format.eColorFormat, usingNativeBuffers, &flexibleEquivalent)
25860d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && colorFormat == flexibleEquivalent) {
2587229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            ALOGI("[%s] using color format %#x in place of %#x",
2588229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                    mComponentName.c_str(), format.eColorFormat, colorFormat);
2589229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            colorFormat = format.eColorFormat;
2590229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
2591229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
2592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The following assertion is violated by TI's video decoder.
2593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // CHECK_EQ(format.nIndex, index);
2594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
2596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexInput
2597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && colorFormat == format.eColorFormat) {
2598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eCompressionFormat does not seem right.
2599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
2600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
2601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexOutput
2603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && compressionFormat == format.eCompressionFormat) {
2604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eColorFormat does not seem right.
2605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
2606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
2607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (format.eCompressionFormat == compressionFormat
2611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && format.eColorFormat == colorFormat) {
2612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            found = true;
2613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ++index;
2617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!found) {
2620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return UNKNOWN_ERROR;
2621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->setParameter(
2624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
2625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
2626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
2628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
26300d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// Set optimal output format. OMX component lists output formats in the order
26310d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// of preference, but this got more complicated since the introduction of flexible
26320d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// YUV formats. We support a legacy behavior for applications that do not use
26330d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// surface output, do not specify an output format, but expect a "usable" standard
26340d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// OMX format. SW readable and standard formats must be flex-YUV.
26350d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar//
26360d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// Suggested preference order:
26370d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal format for texture rendering (mediaplayer behavior)
26380d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal SW readable & texture renderable format (flex-YUV support)
26390d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal SW readable non-renderable format (flex-YUV bytebuffer support)
26400d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - legacy "usable" standard formats
26410d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar//
26420d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// For legacy support, we prefer a standard format, but will settle for a SW readable
26430d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// flex-YUV format.
26440d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnarstatus_t ACodec::setSupportedOutputFormat(bool getLegacyFlexibleFormat) {
26450d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    OMX_VIDEO_PARAM_PORTFORMATTYPE format, legacyFormat;
2646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
2647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = kPortIndexOutput;
2648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
26490d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    InitOMXParams(&legacyFormat);
26500d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    // this field will change when we find a suitable legacy format
26510d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    legacyFormat.eColorFormat = OMX_COLOR_FormatUnused;
2652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
26530d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    for (OMX_U32 index = 0; ; ++index) {
26540d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        format.nIndex = index;
26550d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        status_t err = mOMX->getParameter(
26560d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                mNode, OMX_IndexParamVideoPortFormat,
26570d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                &format, sizeof(format));
26580d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (err != OK) {
26590d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            // no more formats, pick legacy format if found
26600d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            if (legacyFormat.eColorFormat != OMX_COLOR_FormatUnused) {
26610d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                 memcpy(&format, &legacyFormat, sizeof(format));
26620d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                 break;
26630d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            }
26640d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            return err;
26650d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
26660d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (format.eCompressionFormat != OMX_VIDEO_CodingUnused) {
26670d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            return OMX_ErrorBadParameter;
26680d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
26690d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (!getLegacyFlexibleFormat) {
26700d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            break;
26710d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
26720d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        // standard formats that were exposed to users before
26730d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (format.eColorFormat == OMX_COLOR_FormatYUV420Planar
26740d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_COLOR_FormatYUV420PackedPlanar
26750d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar
26760d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_COLOR_FormatYUV420PackedSemiPlanar
26770d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar) {
26780d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            break;
26790d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
26800d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        // find best legacy non-standard format
26810d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        OMX_U32 flexibleEquivalent;
26820d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (legacyFormat.eColorFormat == OMX_COLOR_FormatUnused
26830d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && isFlexibleColorFormat(
26840d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        mOMX, mNode, format.eColorFormat, false /* usingNativeBuffers */,
26850d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        &flexibleEquivalent)
26860d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && flexibleEquivalent == OMX_COLOR_FormatYUV420Flexible) {
26870d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            memcpy(&legacyFormat, &format, sizeof(format));
26880d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
26890d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    }
2690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mOMX->setParameter(
2691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
2692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
2693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2695e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic const struct VideoCodingMapEntry {
2696e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    const char *mMime;
2697e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    OMX_VIDEO_CODINGTYPE mVideoCodingType;
2698e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber} kVideoCodingMapEntry[] = {
2699e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC },
27002472b1c0d63454e5d90a982bd6c555de6c3127bdRachad    { MEDIA_MIMETYPE_VIDEO_HEVC, OMX_VIDEO_CodingHEVC },
2701e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 },
2702e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 },
2703e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 },
270494705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 },
270594705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 },
2706e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber};
2707e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
27085778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic status_t GetVideoCodingTypeFromMime(
27095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
2710e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
2711e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
2712e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
2713e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) {
2714e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *codingType = kVideoCodingMapEntry[i].mVideoCodingType;
2715e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
2716e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
2717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2719e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    *codingType = OMX_VIDEO_CodingUnused;
2720e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2721e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
2722e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
2723e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2724e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic status_t GetMimeTypeForVideoCoding(
2725e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        OMX_VIDEO_CODINGTYPE codingType, AString *mime) {
2726e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
2727e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
2728e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
2729e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) {
2730e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *mime = kVideoCodingMapEntry[i].mMime;
2731e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
2732e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
2733e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
2734e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2735e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    mime->clear();
2736e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2737e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
27385778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
27395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27405778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoDecoder(
27410d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        const char *mime, const sp<AMessage> &msg, bool haveNativeWindow) {
274289869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    int32_t width, height;
274389869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    if (!msg->findInt32("width", &width)
274489869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            || !msg->findInt32("height", &height)) {
274589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        return INVALID_OPERATION;
274689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    }
274789869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar
27485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
27495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
27505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
27525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
27535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
2756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
2757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
276289869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    int32_t tmp;
276389869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    if (msg->findInt32("color-format", &tmp)) {
276489869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        OMX_COLOR_FORMATTYPE colorFormat =
276589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            static_cast<OMX_COLOR_FORMATTYPE>(tmp);
276689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        err = setVideoPortFormatType(
27670d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                kPortIndexOutput, OMX_VIDEO_CodingUnused, colorFormat, haveNativeWindow);
276889869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        if (err != OK) {
276989869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            ALOGW("[%s] does not support color format %d",
277089869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar                  mComponentName.c_str(), colorFormat);
27710d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            err = setSupportedOutputFormat(!haveNativeWindow /* getLegacyFlexibleFormat */);
277289869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        }
277389869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    } else {
27740d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        err = setSupportedOutputFormat(!haveNativeWindow /* getLegacyFlexibleFormat */);
277589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    }
2776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
278178b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    int32_t frameRateInt;
278278b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    float frameRateFloat;
278378b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    if (!msg->findFloat("frame-rate", &frameRateFloat)) {
278478b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        if (!msg->findInt32("frame-rate", &frameRateInt)) {
278578b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            frameRateInt = -1;
278678b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        }
278778b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        frameRateFloat = (float)frameRateInt;
278878b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    }
278978b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad
2790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
279178b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            kPortIndexInput, width, height, compressionFormat, frameRateFloat);
2792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
2798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
2799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
28075778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) {
28085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
28095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("color-format", &tmp)) {
28105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
28115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_COLOR_FORMATTYPE colorFormat =
28145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        static_cast<OMX_COLOR_FORMATTYPE>(tmp);
28155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setVideoPortFormatType(
28175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
28185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
28205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support color format %d",
28215778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str(), colorFormat);
28225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
28245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Input port configuration */
28275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
28295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&def);
28305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
28325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexInput;
28345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
28365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
28375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
28395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
28405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t width, height, bitrate;
28435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("width", &width)
28445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("height", &height)
28455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("bitrate", &bitrate)) {
28465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
28475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
28505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
28515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t stride;
28535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("stride", &stride)) {
28545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        stride = width;
28555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nStride = stride;
28585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t sliceHeight;
28605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("slice-height", &sliceHeight)) {
28615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sliceHeight = height;
28625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nSliceHeight = sliceHeight;
28655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
28675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
28695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
28705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
28715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
28725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
28735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
28745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
28752c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        mTimePerFrameUs = (int64_t) (1000000.0f / frameRate);
28765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
28795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
2880a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    // this is redundant as it was already set up in setVideoPortFormatType
2881a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    // FIXME for now skip this only for flexible YUV formats
2882a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    if (colorFormat != OMX_COLOR_FormatYUV420Flexible) {
2883a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar        video_def->eColorFormat = colorFormat;
2884a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    }
28855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
28875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
28885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
28905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set input port definition parameters.",
28915778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
28925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
28945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Output port configuration */
28975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
28995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
29005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
29025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
29035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
29065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
29075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
29095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support compression format %d",
29105778822d86b0337407514b9372562b86edfa91cdAndreas Huber             mComponentName.c_str(), compressionFormat);
29115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
29135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexOutput;
29165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
29185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
29195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
29215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
29225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
29255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
29265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = 0;
29275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nBitrate = bitrate;
29285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = compressionFormat;
29295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = OMX_COLOR_FormatUnused;
29305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
29325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
29335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
29355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set output port definition parameters.",
29365778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
29375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
29395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (compressionFormat) {
29425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingMPEG4:
29435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupMPEG4EncoderParameters(msg);
29445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
29455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingH263:
29475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupH263EncoderParameters(msg);
29485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
29495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingAVC:
29515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupAVCEncoderParameters(msg);
29525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
29535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2954c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        case OMX_VIDEO_CodingHEVC:
2955c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            err = setupHEVCEncoderParameters(msg);
2956c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            break;
2957c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
295889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP8:
295989b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP9:
296089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            err = setupVPXEncoderParameters(msg);
296189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            break;
296289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
29635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
29645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
29655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2967d36a023778256f0550e9a09e9993c066e8a3c7d7Ronghua Wu    if (err == OK) {
2968d36a023778256f0550e9a09e9993c066e8a3c7d7Ronghua Wu        ALOGI("setupVideoEncoder succeeded");
2969d36a023778256f0550e9a09e9993c066e8a3c7d7Ronghua Wu    }
29705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
29725778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
29735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29740dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dongstatus_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) {
29750dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    OMX_VIDEO_PARAM_INTRAREFRESHTYPE params;
29760dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    InitOMXParams(&params);
29770dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.nPortIndex = kPortIndexOutput;
29780dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
29790dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode);
29800dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
29810dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic ||
29820dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
29830dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
29840dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) {
29850dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
29860dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
29870dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nCirMBs = mbs;
29880dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
29890dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
29900dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive ||
29910dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
29920dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
29930dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) {
29940dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
29950dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
29960dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirMBs = mbs;
29970dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
29980dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t ref;
29990dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) {
30000dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
30010dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
30020dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirRef = ref;
30030dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
30040dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
30050dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = mOMX->setParameter(
30060dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            mNode, OMX_IndexParamVideoIntraRefresh,
30070dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            &params, sizeof(params));
30080dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    return err;
30090dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong}
30100dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
30115778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
30125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (iFramesInterval < 0) {
30135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0xFFFFFFFF;
30145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (iFramesInterval == 0) {
30155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0;
30165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
30175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_U32 ret = frameRate * iFramesInterval;
30185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return ret;
30195778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
30205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
302196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatic OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) {
302296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    int32_t tmp;
302396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    if (!msg->findInt32("bitrate-mode", &tmp)) {
302496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        return OMX_Video_ControlRateVariable;
302596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    }
302696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
302796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp);
302896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber}
302996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
30305778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
30315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
30325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
30335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
30345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
30355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
30365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
303796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
303896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
30395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
30405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
30415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
30425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
30435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
30445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
30455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
30465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
30475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
30495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&mpeg4type);
30505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPortIndex = kPortIndexOutput;
30515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
30535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
30545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
30565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
30575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
30585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nSliceHeaderSpacing = 0;
30605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bSVH = OMX_FALSE;
30615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bGov = OMX_FALSE;
30625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nAllowedPictureTypes =
30645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
30655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
30675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mpeg4type.nPFrames == 0) {
30685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
30695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
30705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nBFrames = 0;
30715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nIDCVLCThreshold = 0;
30725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bACPred = OMX_TRUE;
30735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nMaxPacketSize = 256;
30745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nTimeIncRes = 1000;
30755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nHeaderExtension = 0;
30765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bReversibleVLC = OMX_FALSE;
30775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
30795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
30805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
30815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
30825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
30835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
30845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
30865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
30885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
30895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
30905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
30925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
30935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
30945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
30965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
30975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
30995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
31005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
31015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
310296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
31035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
31055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
31065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
31075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
31095778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
31105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31115778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
31125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
31135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
31145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
31155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
31165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
31175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
311896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
311996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
31205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
31215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
31225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
31235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
31245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
31255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
31265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
31275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
31285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_H263TYPE h263type;
31305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h263type);
31315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPortIndex = kPortIndexOutput;
31325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
31345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
31355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
31375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
31385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
31395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nAllowedPictureTypes =
31415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
31425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
31445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h263type.nPFrames == 0) {
31455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
31465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
31475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nBFrames = 0;
31485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
31505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
31515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
31525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
31535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
31545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
31555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
31575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
31595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
31605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
31615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
31635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
31645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
31655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bPLUSPTYPEAllowed = OMX_FALSE;
31675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bForceRoundingTypeToZero = OMX_FALSE;
31685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPictureHeaderRepetition = 0;
31695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nGOBHeaderInterval = 0;
31705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
31725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
31735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
31755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
31765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
31775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
317896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
31795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
31815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
31825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
31835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
31855778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
31865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3187a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar// static
3188a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnarint /* OMX_VIDEO_AVCLEVELTYPE */ ACodec::getAVCLevelFor(
3189a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        int width, int height, int rate, int bitrate,
3190a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        OMX_VIDEO_AVCPROFILETYPE profile) {
3191a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    // convert bitrate to main/baseline profile kbps equivalent
3192a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    switch (profile) {
3193a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        case OMX_VIDEO_AVCProfileHigh10:
3194a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 3000); break;
3195a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        case OMX_VIDEO_AVCProfileHigh:
3196a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 1250); break;
3197a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        default:
3198a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 1000); break;
3199a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    }
3200a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
3201a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    // convert size and rate to MBs
3202a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    width = divUp(width, 16);
3203a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    height = divUp(height, 16);
3204a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    int mbs = width * height;
3205a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    rate *= mbs;
3206a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    int maxDimension = max(width, height);
3207a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
3208a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    static const int limits[][5] = {
3209a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        /*   MBps     MB   dim  bitrate        level */
3210a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    1485,    99,  28,     64, OMX_VIDEO_AVCLevel1  },
3211a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    1485,    99,  28,    128, OMX_VIDEO_AVCLevel1b },
3212a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    3000,   396,  56,    192, OMX_VIDEO_AVCLevel11 },
3213a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    6000,   396,  56,    384, OMX_VIDEO_AVCLevel12 },
3214a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   11880,   396,  56,    768, OMX_VIDEO_AVCLevel13 },
3215a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   11880,   396,  56,   2000, OMX_VIDEO_AVCLevel2  },
3216a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   19800,   792,  79,   4000, OMX_VIDEO_AVCLevel21 },
3217a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   20250,  1620, 113,   4000, OMX_VIDEO_AVCLevel22 },
3218a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   40500,  1620, 113,  10000, OMX_VIDEO_AVCLevel3  },
3219a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  108000,  3600, 169,  14000, OMX_VIDEO_AVCLevel31 },
3220a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  216000,  5120, 202,  20000, OMX_VIDEO_AVCLevel32 },
3221a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  245760,  8192, 256,  20000, OMX_VIDEO_AVCLevel4  },
3222a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  245760,  8192, 256,  50000, OMX_VIDEO_AVCLevel41 },
3223a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  522240,  8704, 263,  50000, OMX_VIDEO_AVCLevel42 },
3224a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  589824, 22080, 420, 135000, OMX_VIDEO_AVCLevel5  },
3225a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  983040, 36864, 543, 240000, OMX_VIDEO_AVCLevel51 },
3226a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        { 2073600, 36864, 543, 240000, OMX_VIDEO_AVCLevel52 },
3227a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    };
3228a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
3229a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    for (size_t i = 0; i < ARRAY_SIZE(limits); i++) {
3230a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        const int (&limit)[5] = limits[i];
3231a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        if (rate <= limit[0] && mbs <= limit[1] && maxDimension <= limit[2]
3232a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar                && bitrate <= limit[3]) {
3233a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            return limit[4];
3234a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        }
3235a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    }
3236a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    return 0;
3237a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar}
3238a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
32395778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
32405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
32415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
32425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
32435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
32445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
32455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
324696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
324796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
32485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
32495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
32505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
32515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
32525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
32535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
32545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
32555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
32565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32570dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = OK;
32580dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    int32_t intraRefreshMode = 0;
32590dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) {
32600dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode);
32610dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (err != OK) {
32620dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
32630dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong                    err, intraRefreshMode);
32640dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return err;
32650dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
32660dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
32670dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
32685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_AVCTYPE h264type;
32695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h264type);
32705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nPortIndex = kPortIndexOutput;
32715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32720dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    err = mOMX->getParameter(
32735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
32745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
32765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
32775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
32785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nAllowedPictureTypes =
32805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
32815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
32835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
32845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
32855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
32865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
32875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
32885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
32905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
32925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
32935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
32945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
32965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
32975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
32985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // XXX
33007c25df82dfc8bbedb58608242f0d923a4594bb14James Dong    if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) {
33017c25df82dfc8bbedb58608242f0d923a4594bb14James Dong        ALOGW("Use baseline profile instead of %d for AVC recording",
33027c25df82dfc8bbedb58608242f0d923a4594bb14James Dong            h264type.eProfile);
33035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
33045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
33055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
33075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nSliceHeaderSpacing = 0;
33085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bUseHadamard = OMX_TRUE;
33095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefFrames = 1;
33105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nBFrames = 0;
33115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
33125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (h264type.nPFrames == 0) {
33135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
33145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
33155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx10ActiveMinus1 = 0;
33165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx11ActiveMinus1 = 0;
33175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bEntropyCodingCABAC = OMX_FALSE;
33185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bWeightedPPrediction = OMX_FALSE;
33195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bconstIpred = OMX_FALSE;
33205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirect8x8Inference = OMX_FALSE;
33215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirectSpatialTemporal = OMX_FALSE;
33225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nCabacInitIdc = 0;
33235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
33245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.nBFrames != 0) {
33265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
33275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
33285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableUEP = OMX_FALSE;
33305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableFMO = OMX_FALSE;
33315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableASO = OMX_FALSE;
33325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableRS = OMX_FALSE;
33335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bFrameMBsOnly = OMX_TRUE;
33345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bMBAFF = OMX_FALSE;
33355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
33365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
33385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
33395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
33415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
33425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
33435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
334496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return configureBitrate(bitrate, bitrateMode);
33455778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
33465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3347c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachadstatus_t ACodec::setupHEVCEncoderParameters(const sp<AMessage> &msg) {
3348c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    int32_t bitrate, iFrameInterval;
3349c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findInt32("bitrate", &bitrate)
3350c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
3351c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return INVALID_OPERATION;
3352c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
3353c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3354c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
3355c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3356c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    float frameRate;
3357c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findFloat("frame-rate", &frameRate)) {
3358c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t tmp;
3359c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("frame-rate", &tmp)) {
3360c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
3361c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
3362c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        frameRate = (float)tmp;
3363c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
3364c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3365c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_PARAM_HEVCTYPE hevcType;
3366c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    InitOMXParams(&hevcType);
3367c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    hevcType.nPortIndex = kPortIndexOutput;
3368c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3369c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    status_t err = OK;
3370c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    err = mOMX->getParameter(
3371c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
3372c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
3373c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
3374c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
3375c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3376c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    int32_t profile;
3377c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (msg->findInt32("profile", &profile)) {
3378c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t level;
3379c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("level", &level)) {
3380c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
3381c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
3382c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3383c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        err = verifySupportForProfileAndLevel(profile, level);
3384c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (err != OK) {
3385c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return err;
3386c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
3387c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3388c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eProfile = static_cast<OMX_VIDEO_HEVCPROFILETYPE>(profile);
3389c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eLevel = static_cast<OMX_VIDEO_HEVCLEVELTYPE>(level);
3390c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
3391c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3392c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    // TODO: Need OMX structure definition for setting iFrameInterval
3393c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3394c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    err = mOMX->setParameter(
3395c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
3396c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
3397c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
3398c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
3399c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3400c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    return configureBitrate(bitrate, bitrateMode);
3401c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad}
3402c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
340389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huberstatus_t ACodec::setupVPXEncoderParameters(const sp<AMessage> &msg) {
340489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    int32_t bitrate;
34054154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    int32_t iFrameInterval = 0;
34064154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    size_t tsLayers = 0;
34074154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE pattern =
34084154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        OMX_VIDEO_VPXTemporalLayerPatternNone;
34094154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    static const uint32_t kVp8LayerRateAlloction
34104154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS]
34114154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS] = {
34124154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        {100, 100, 100},  // 1 layer
34134154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 60, 100, 100},  // 2 layers {60%, 40%}
34144154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 40,  60, 100},  // 3 layers {40%, 20%, 40%}
34154154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    };
341689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    if (!msg->findInt32("bitrate", &bitrate)) {
341789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        return INVALID_OPERATION;
341889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    }
34194154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    msg->findInt32("i-frame-interval", &iFrameInterval);
342089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
342189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
342289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
34234154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    float frameRate;
34244154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (!msg->findFloat("frame-rate", &frameRate)) {
34254154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        int32_t tmp;
34264154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (!msg->findInt32("frame-rate", &tmp)) {
34274154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            return INVALID_OPERATION;
34284154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
34294154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        frameRate = (float)tmp;
34304154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
34314154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
34324154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    AString tsSchema;
34334154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (msg->findString("ts-schema", &tsSchema)) {
34344154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (tsSchema == "webrtc.vp8.1-layer") {
34354154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
34364154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 1;
34374154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else if (tsSchema == "webrtc.vp8.2-layer") {
34384154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
34394154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 2;
34404154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else if (tsSchema == "webrtc.vp8.3-layer") {
34414154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
34424154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 3;
34434154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else {
34444154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            ALOGW("Unsupported ts-schema [%s]", tsSchema.c_str());
34454154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
34464154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
34474154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
34484154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
34494154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    InitOMXParams(&vp8type);
34504154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    vp8type.nPortIndex = kPortIndexOutput;
34514154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    status_t err = mOMX->getParameter(
34524154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
34534154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            &vp8type, sizeof(vp8type));
34544154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
34554154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (err == OK) {
34564154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (iFrameInterval > 0) {
34574154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nKeyFrameInterval = setPFramesSpacing(iFrameInterval, frameRate);
34584154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
34594154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.eTemporalPattern = pattern;
34604154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.nTemporalLayerCount = tsLayers;
34614154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (tsLayers > 0) {
34624154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            for (size_t i = 0; i < OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS; i++) {
34634154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                vp8type.nTemporalLayerBitrateRatio[i] =
34644154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                    kVp8LayerRateAlloction[tsLayers - 1][i];
34654154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            }
34664154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
34674154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (bitrateMode == OMX_Video_ControlRateConstant) {
34684154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMinQuantizer = 2;
34694154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMaxQuantizer = 63;
34704154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
34714154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
34724154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        err = mOMX->setParameter(
34734154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
34744154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                &vp8type, sizeof(vp8type));
34754154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (err != OK) {
34764154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            ALOGW("Extended VP8 parameters set failed: %d", err);
34774154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
34784154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
34794154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
348089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    return configureBitrate(bitrate, bitrateMode);
348189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber}
348289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
34835778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::verifySupportForProfileAndLevel(
34845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t profile, int32_t level) {
34855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
34865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&params);
34875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    params.nPortIndex = kPortIndexOutput;
34885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (params.nProfileIndex = 0;; ++params.nProfileIndex) {
34905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
34915778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode,
34925778822d86b0337407514b9372562b86edfa91cdAndreas Huber                OMX_IndexParamVideoProfileLevelQuerySupported,
34935778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &params,
34945778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sizeof(params));
34955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
34975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
34985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
34995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
35015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
35025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (profile == supportedProfile && level <= supportedLevel) {
35045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OK;
35055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
35065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
35075778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
35085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
350996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatus_t ACodec::configureBitrate(
351096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) {
35115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
35125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&bitrateType);
35135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
35145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
35165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
35175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
35185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
35205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
35215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
35225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
352396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    bitrateType.eControlRate = bitrateMode;
35245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nTargetBitrate = bitrate;
35255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
35275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
35285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
35295778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
35305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35315778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupErrorCorrectionParameters() {
35325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
35335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&errorCorrectionType);
35345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nPortIndex = kPortIndexOutput;
35355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
35375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
35385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
35395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
35415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OK;  // Optional feature. Ignore this failure
35425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
35435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableHEC = OMX_FALSE;
35455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableResync = OMX_TRUE;
35465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nResynchMarkerSpacing = 256;
35475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
35485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableRVLC = OMX_FALSE;
35495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
35515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
35525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
35535778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
35545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3555f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoFormatOnPort(
3556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
355778b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat,
355878b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        float frameRate) {
3559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
3560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
3561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
3562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
3564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
3566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
3567777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (err != OK) {
3568777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return err;
3569777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
3570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
3572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // XXX Need a (much) better heuristic to compute input buffer sizes.
3573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const size_t X = 64 * 1024;
3574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (def.nBufferSize < X) {
3575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.nBufferSize = X;
3576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3579777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (def.eDomain != OMX_PortDomainVideo) {
3580777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("expected video port, got %s(%d)", asString(def.eDomain), def.eDomain);
3581777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return FAILED_TRANSACTION;
3582777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
3583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameWidth = width;
3585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameHeight = height;
3586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
3588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eCompressionFormat = compressionFormat;
3589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eColorFormat = OMX_COLOR_FormatUnused;
359078b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        if (frameRate >= 0) {
359178b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
359278b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        }
3593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
3596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
3597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
3599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3601f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::initNativeWindow() {
3602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL) {
3603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
3604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
3607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
3608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3610d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Hubersize_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
3611d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    size_t n = 0;
3612d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
3613d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
3614d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        const BufferInfo &info = mBuffers[portIndex].itemAt(i);
3615d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
3616d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
3617d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            ++n;
3618d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        }
3619d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    }
3620d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
3621d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    return n;
3622d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber}
3623d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
36247e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubersize_t ACodec::countBuffersOwnedByNativeWindow() const {
36257e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    size_t n = 0;
36267e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
36277e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
36287e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
36297e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
36307e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
36317e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            ++n;
36327e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        }
36337e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
36347e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
36357e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    return n;
36367e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
36377e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
36387e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubervoid ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
36397e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (mNativeWindow == NULL) {
36407e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        return;
36417e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
36427e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
3643e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    while (countBuffersOwnedByNativeWindow() > mNumUndequeuedBuffers
36447e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            && dequeueBufferFromNativeWindow() != NULL) {
3645c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        // these buffers will be submitted as regular buffers; account for this
3646054219874873b41f1c815552987c10465c34ba2bLajos Molnar        if (storingMetadataInDecodedBuffers() && mMetadataBuffersToSubmit > 0) {
3647054219874873b41f1c815552987c10465c34ba2bLajos Molnar            --mMetadataBuffersToSubmit;
3648c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        }
36497e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
36507e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
36517e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
3652f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs(
3653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
3654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
3655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
3656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus != BufferInfo::OWNED_BY_US
3658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3659609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGV("[%s] Buffer %u on port %u still has status %d",
3660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mComponentName.c_str(),
3661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info->mBufferID, portIndex, info->mStatus);
3662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
3663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3669f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs() {
3670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return allYourBuffersAreBelongToUs(kPortIndexInput)
3671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        && allYourBuffersAreBelongToUs(kPortIndexOutput);
3672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3674f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::deferMessage(const sp<AMessage> &msg) {
3675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.push_back(msg);
3676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3678f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::processDeferredMessages() {
3679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> > queue = mDeferredQueue;
3680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.clear();
3681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> >::iterator it = queue.begin();
3683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while (it != queue.end()) {
3684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        onMessageReceived(*it++);
3685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
368803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar// static
3689229d242665c612fd97431d1e7ac004823b47f181Lajos Molnarbool ACodec::describeDefaultColorFormat(DescribeColorFormatParams &params) {
369003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    MediaImage &image = params.sMediaImage;
369103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    memset(&image, 0, sizeof(image));
369203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
369303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mType = MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
369403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mNumPlanes = 0;
369503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
369603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    const OMX_COLOR_FORMATTYPE fmt = params.eColorFormat;
369703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mWidth = params.nFrameWidth;
369803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mHeight = params.nFrameHeight;
369903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
370003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    // only supporting YUV420
370103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    if (fmt != OMX_COLOR_FormatYUV420Planar &&
370203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        fmt != OMX_COLOR_FormatYUV420PackedPlanar &&
370303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        fmt != OMX_COLOR_FormatYUV420SemiPlanar &&
37045a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        fmt != OMX_COLOR_FormatYUV420PackedSemiPlanar &&
37055a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        fmt != HAL_PIXEL_FORMAT_YV12) {
370603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        ALOGW("do not know color format 0x%x = %d", fmt, fmt);
3707229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return false;
370803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    }
370903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
3710b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    // TEMPORARY FIX for some vendors that advertise sliceHeight as 0
3711b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    if (params.nStride != 0 && params.nSliceHeight == 0) {
3712b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        ALOGW("using sliceHeight=%u instead of what codec advertised (=0)",
3713b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar                params.nFrameHeight);
3714b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        params.nSliceHeight = params.nFrameHeight;
3715b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    }
3716b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar
3717b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    // we need stride and slice-height to be non-zero
3718b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    if (params.nStride == 0 || params.nSliceHeight == 0) {
3719b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        ALOGW("cannot describe color format 0x%x = %d with stride=%u and sliceHeight=%u",
3720b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar                fmt, fmt, params.nStride, params.nSliceHeight);
3721b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        return false;
3722b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    }
3723b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar
372403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    // set-up YUV format
372503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mType = MediaImage::MEDIA_IMAGE_TYPE_YUV;
372603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mNumPlanes = 3;
372703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mBitDepth = 8;
372803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mOffset = 0;
372903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mColInc = 1;
373003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mRowInc = params.nStride;
373103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mHorizSubsampling = 1;
373203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mVertSubsampling = 1;
373303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
37345a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar    switch ((int)fmt) {
37355a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        case HAL_PIXEL_FORMAT_YV12:
37365a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            if (params.bUsingNativeBuffers) {
37375a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                size_t ystride = align(params.nStride, 16);
37385a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                size_t cstride = align(params.nStride / 2, 16);
37395a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.Y].mRowInc = ystride;
37405a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
37415a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mOffset = ystride * params.nSliceHeight;
37425a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mColInc = 1;
37435a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mRowInc = cstride;
37445a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mHorizSubsampling = 2;
37455a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mVertSubsampling = 2;
37465a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
37475a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mOffset = image.mPlane[image.V].mOffset
37485a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                        + (cstride * params.nSliceHeight / 2);
37495a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mColInc = 1;
37505a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mRowInc = cstride;
37515a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mHorizSubsampling = 2;
37525a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mVertSubsampling = 2;
37535a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                break;
37545a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            } else {
37555a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                // fall through as YV12 is used for YUV420Planar by some codecs
37565a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            }
37575a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
37585a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        case OMX_COLOR_FormatYUV420Planar:
375903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420PackedPlanar:
376003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight;
376103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mColInc = 1;
376203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mRowInc = params.nStride / 2;
376303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mHorizSubsampling = 2;
376403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mVertSubsampling = 2;
376503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
376603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset
376703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    + (params.nStride * params.nSliceHeight / 4);
376803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mColInc = 1;
376903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mRowInc = params.nStride / 2;
377003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mHorizSubsampling = 2;
377103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mVertSubsampling = 2;
377203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            break;
377303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
377403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420SemiPlanar:
377503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            // FIXME: NV21 for sw-encoder, NV12 for decoder and hw-encoder
377603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420PackedSemiPlanar:
377703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            // NV12
377803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight;
377903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mColInc = 2;
378003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mRowInc = params.nStride;
378103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mHorizSubsampling = 2;
378203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mVertSubsampling = 2;
378303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
378403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset + 1;
378503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mColInc = 2;
378603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mRowInc = params.nStride;
378703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mHorizSubsampling = 2;
378803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mVertSubsampling = 2;
378903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            break;
379003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
379103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        default:
379203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            TRESPASS();
379303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    }
3794229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    return true;
3795229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar}
3796229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3797229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar// static
3798229d242665c612fd97431d1e7ac004823b47f181Lajos Molnarbool ACodec::describeColorFormat(
3799229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        const sp<IOMX> &omx, IOMX::node_id node,
3800229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        DescribeColorFormatParams &describeParams)
3801229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar{
3802229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    OMX_INDEXTYPE describeColorFormatIndex;
3803229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    if (omx->getExtensionIndex(
3804229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            node, "OMX.google.android.index.describeColorFormat",
3805229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            &describeColorFormatIndex) != OK ||
3806229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        omx->getParameter(
3807229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            node, describeColorFormatIndex,
3808229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            &describeParams, sizeof(describeParams)) != OK) {
3809229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return describeDefaultColorFormat(describeParams);
3810229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    }
3811229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    return describeParams.sMediaImage.mType !=
3812229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
3813229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar}
3814229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3815229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar// static
3816229d242665c612fd97431d1e7ac004823b47f181Lajos Molnarbool ACodec::isFlexibleColorFormat(
3817229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar         const sp<IOMX> &omx, IOMX::node_id node,
38180d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar         uint32_t colorFormat, bool usingNativeBuffers, OMX_U32 *flexibleEquivalent) {
3819229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    DescribeColorFormatParams describeParams;
3820229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    InitOMXParams(&describeParams);
3821229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.eColorFormat = (OMX_COLOR_FORMATTYPE)colorFormat;
3822229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    // reasonable dummy values
3823229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nFrameWidth = 128;
3824229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nFrameHeight = 128;
3825229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nStride = 128;
3826229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nSliceHeight = 128;
38270d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    describeParams.bUsingNativeBuffers = (OMX_BOOL)usingNativeBuffers;
3828229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3829229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    CHECK(flexibleEquivalent != NULL);
3830229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3831229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    if (!describeColorFormat(omx, node, describeParams)) {
3832229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return false;
3833229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    }
3834229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3835229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    const MediaImage &img = describeParams.sMediaImage;
3836229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    if (img.mType == MediaImage::MEDIA_IMAGE_TYPE_YUV) {
3837229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        if (img.mNumPlanes != 3 ||
3838229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            img.mPlane[img.Y].mHorizSubsampling != 1 ||
3839229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            img.mPlane[img.Y].mVertSubsampling != 1) {
3840229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            return false;
3841229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
3842229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3843229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        // YUV 420
3844229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        if (img.mPlane[img.U].mHorizSubsampling == 2
3845229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.U].mVertSubsampling == 2
3846229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.V].mHorizSubsampling == 2
3847229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.V].mVertSubsampling == 2) {
3848229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            // possible flexible YUV420 format
3849229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            if (img.mBitDepth <= 8) {
3850229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar               *flexibleEquivalent = OMX_COLOR_FormatYUV420Flexible;
3851229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar               return true;
3852229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            }
3853229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
3854229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    }
3855229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    return false;
385603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar}
385703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
3858e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarstatus_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> &notify) {
3859777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    const char *niceIndex = portIndex == kPortIndexInput ? "input" : "output";
386031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
386131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    InitOMXParams(&def);
3862e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    def.nPortIndex = portIndex;
386331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3864777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    status_t err = mOMX->getParameter(mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
3865777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (err != OK) {
3866777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return err;
3867777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
386831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3869777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (def.eDir != (portIndex == kPortIndexOutput ? OMX_DirOutput : OMX_DirInput)) {
3870777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("unexpected dir: %s(%d) on %s port", asString(def.eDir), def.eDir, niceIndex);
3871777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return BAD_VALUE;
3872777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
387331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
387431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    switch (def.eDomain) {
387531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainVideo:
387631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
387731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
3878e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            switch ((int)videoDef->eCompressionFormat) {
3879e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_VIDEO_CodingUnused:
3880e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3881e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(mIsEncoder ^ (portIndex == kPortIndexOutput));
3882e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
3883e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3884e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("stride", videoDef->nStride);
3885e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("slice-height", videoDef->nSliceHeight);
3886e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("color-format", videoDef->eColorFormat);
3887e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
38880d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                    if (mNativeWindow == NULL) {
38890d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        DescribeColorFormatParams describeParams;
38900d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        InitOMXParams(&describeParams);
38910d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.eColorFormat = videoDef->eColorFormat;
38920d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nFrameWidth = videoDef->nFrameWidth;
38930d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nFrameHeight = videoDef->nFrameHeight;
38940d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nStride = videoDef->nStride;
38950d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nSliceHeight = videoDef->nSliceHeight;
38960d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.bUsingNativeBuffers = OMX_FALSE;
38970d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar
38980d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        if (describeColorFormat(mOMX, mNode, describeParams)) {
38990d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                            notify->setBuffer(
39000d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                    "image-data",
39010d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                    ABuffer::CreateAsCopy(
39020d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                            &describeParams.sMediaImage,
39030d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                            sizeof(describeParams.sMediaImage)));
39045a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
39055a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                            MediaImage *img = &describeParams.sMediaImage;
39065a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                            ALOGV("[%s] MediaImage { F(%zux%zu) @%zu+%zu+%zu @%zu+%zu+%zu @%zu+%zu+%zu }",
39075a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                                    mComponentName.c_str(), img->mWidth, img->mHeight,
39085a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                                    img->mPlane[0].mOffset, img->mPlane[0].mColInc, img->mPlane[0].mRowInc,
39095a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                                    img->mPlane[1].mOffset, img->mPlane[1].mColInc, img->mPlane[1].mRowInc,
39105a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                                    img->mPlane[2].mOffset, img->mPlane[2].mColInc, img->mPlane[2].mRowInc);
39110d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        }
391203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    }
391303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
391491a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                    if (portIndex != kPortIndexOutput) {
391591a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                        // TODO: also get input crop
391691a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                        break;
391791a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                    }
391891a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar
3919e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_CONFIG_RECTTYPE rect;
3920e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&rect);
392191a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                    rect.nPortIndex = portIndex;
3922e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3923e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    if (mOMX->getConfig(
392491a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                mNode,
392591a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                (portIndex == kPortIndexOutput ?
392691a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                        OMX_IndexConfigCommonOutputCrop :
392791a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                        OMX_IndexConfigCommonInputCrop),
3928e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &rect, sizeof(rect)) != OK) {
3929e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nLeft = 0;
3930e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nTop = 0;
3931e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nWidth = videoDef->nFrameWidth;
3932e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nHeight = videoDef->nFrameHeight;
3933e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    }
393431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3935777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (rect.nLeft < 0 ||
3936777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        rect.nTop < 0 ||
3937777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        rect.nLeft + rect.nWidth > videoDef->nFrameWidth ||
3938777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        rect.nTop + rect.nHeight > videoDef->nFrameHeight) {
3939777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        ALOGE("Wrong cropped rect (%d, %d) - (%u, %u) vs. frame (%u, %u)",
3940777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                rect.nLeft, rect.nTop,
3941777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                rect.nLeft + rect.nWidth, rect.nTop + rect.nHeight,
3942777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                videoDef->nFrameWidth, videoDef->nFrameHeight);
3943777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return BAD_VALUE;
3944777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
3945e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3946e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setRect(
3947577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            "crop",
3948577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nLeft,
3949577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nTop,
3950e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                            rect.nLeft + rect.nWidth - 1,
3951e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                            rect.nTop + rect.nHeight - 1);
3952e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3953e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3954e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
39554730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
39564730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP8:
39574730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP9:
39584730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                {
39594730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
39604730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    InitOMXParams(&vp8type);
39614730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    vp8type.nPortIndex = kPortIndexOutput;
39624730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    status_t err = mOMX->getParameter(
39634730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            mNode,
39644730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
39654730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            &vp8type,
39664730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            sizeof(vp8type));
39674730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
39684730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    if (err == OK) {
39694730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        AString tsSchema = "none";
39704730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        if (vp8type.eTemporalPattern
39714730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                == OMX_VIDEO_VPXTemporalLayerPatternWebRTC) {
39724730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            switch (vp8type.nTemporalLayerCount) {
39734730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 1:
39744730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
39754730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.1-layer";
39764730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
39774730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
39784730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 2:
39794730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
39804730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.2-layer";
39814730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
39824730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
39834730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 3:
39844730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
39854730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.3-layer";
39864730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
39874730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
39884730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                default:
39894730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
39904730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
39914730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
39924730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            }
39934730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        }
39944730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        notify->setString("ts-schema", tsSchema);
39954730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    }
39964730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    // Fall through to set up mime.
39974730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                }
39984730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
3999e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                default:
4000e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
4001777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (mIsEncoder ^ (portIndex == kPortIndexOutput)) {
4002777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        // should be CodingUnused
4003777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        ALOGE("Raw port video compression format is %s(%d)",
4004777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                asString(videoDef->eCompressionFormat),
4005777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                videoDef->eCompressionFormat);
4006777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return BAD_VALUE;
4007777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4008e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    AString mime;
4009e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    if (GetMimeTypeForVideoCoding(
4010e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        videoDef->eCompressionFormat, &mime) != OK) {
4011e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", "application/octet-stream");
4012e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    } else {
4013e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", mime.c_str());
4014e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    }
4015e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
4016e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
401731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            }
4018e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("width", videoDef->nFrameWidth);
4019e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("height", videoDef->nFrameHeight);
40205a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            ALOGV("[%s] %s format is %s", mComponentName.c_str(),
40215a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                    portIndex == kPortIndexInput ? "input" : "output",
40225a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                    notify->debugString().c_str());
40235a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
402431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
402531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
402631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
402731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainAudio:
402831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
402931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
403031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
403197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            switch ((int)audioDef->eEncoding) {
4032e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingPCM:
4033e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
4034e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_PCMMODETYPE params;
4035e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
4036e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
4037e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4038777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4039777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, OMX_IndexParamAudioPcm, &params, sizeof(params));
4040777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4041777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4042777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
404314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
4044777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (params.nChannels <= 0
4045777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            || (params.nChannels != 1 && !params.bInterleaved)
4046777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            || params.nBitPerSample != 16u
4047777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            || params.eNumData != OMX_NumericalDataSigned
4048777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            || params.ePCMMode != OMX_AUDIO_PCMModeLinear) {
4049777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        ALOGE("unsupported PCM port: %u channels%s, %u-bit, %s(%d), %s(%d) mode ",
4050777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                params.nChannels,
4051777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                params.bInterleaved ? " interleaved" : "",
4052777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                params.nBitPerSample,
4053777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                asString(params.eNumData), params.eNumData,
4054777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                asString(params.ePCMMode), params.ePCMMode);
4055777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return FAILED_TRANSACTION;
4056777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4057e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4058e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
4059e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
4060e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSamplingRate);
4061e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4062e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mChannelMaskPresent) {
4063e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("channel-mask", mChannelMask);
40648b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                    }
4065e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
40668b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                }
40679806555d3930be43e11106281dee354820ac1c88Andreas Huber
4068e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAAC:
4069e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
4070e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AACPROFILETYPE params;
4071e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
4072e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
4073e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4074777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4075777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, OMX_IndexParamAudioAac, &params, sizeof(params));
4076777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4077777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4078777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4079e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4080e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
4081e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
4082e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
4083e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
4084e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
4085e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4086e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAMR:
4087e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
4088e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AMRTYPE params;
4089e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
4090e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
40919806555d3930be43e11106281dee354820ac1c88Andreas Huber
4092777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4093777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, OMX_IndexParamAudioAmr, &params, sizeof(params));
4094777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4095777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4096777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4097e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4098e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", 1);
4099e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) {
41000806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_WB);
4101e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 16000);
4102e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    } else {
41030806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
4104e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 8000);
4105e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
4106e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
4107e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
4108e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4109e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingFLAC:
4110e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
4111e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_FLACTYPE params;
4112e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
4113e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
4114e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4115777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4116777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, OMX_IndexParamAudioFlac, &params, sizeof(params));
4117777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4118777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4119777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4120e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4121e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC);
4122e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
4123e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
4124e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
4125e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
4126e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4127e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingMP3:
4128e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
4129e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_MP3TYPE params;
4130e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
4131e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
4132e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4133777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4134777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, OMX_IndexParamAudioMp3, &params, sizeof(params));
4135777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4136777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4137777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4138e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4139e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MPEG);
4140e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
4141e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
4142e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
4143e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
4144e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4145e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingVORBIS:
4146e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
4147e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_VORBISTYPE params;
4148e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
4149e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
4150e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4151777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4152777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, OMX_IndexParamAudioVorbis, &params, sizeof(params));
4153777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4154777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4155777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4156e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4157e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_VORBIS);
4158e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
4159e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
4160e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
4161e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
4162e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
416397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                case OMX_AUDIO_CodingAndroidAC3:
416497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                {
416597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    OMX_AUDIO_PARAM_ANDROID_AC3TYPE params;
416697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    InitOMXParams(&params);
4167e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
416897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
4169777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4170777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
4171777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            &params, sizeof(params));
4172777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4173777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4174777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
417597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
417697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AC3);
417797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("channel-count", params.nChannels);
417897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("sample-rate", params.nSampleRate);
417997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    break;
418097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                }
4181e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
41828a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                case OMX_AUDIO_CodingAndroidEAC3:
41838a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                {
41848a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    OMX_AUDIO_PARAM_ANDROID_EAC3TYPE params;
41858a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    InitOMXParams(&params);
41868a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    params.nPortIndex = portIndex;
41878a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
4188777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4189777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
4190777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            &params, sizeof(params));
4191777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4192777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4193777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
41948a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
41958a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_EAC3);
41968a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setInt32("channel-count", params.nChannels);
41978a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setInt32("sample-rate", params.nSampleRate);
41988a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    break;
41998a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                }
42008a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
42018c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                case OMX_AUDIO_CodingAndroidOPUS:
42028c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                {
42038c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    OMX_AUDIO_PARAM_ANDROID_OPUSTYPE params;
42048c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    InitOMXParams(&params);
42058c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    params.nPortIndex = portIndex;
42068c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
4207777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4208777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus,
4209777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            &params, sizeof(params));
4210777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4211777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4212777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
42138c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
42148c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_OPUS);
42158c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("channel-count", params.nChannels);
42168c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("sample-rate", params.nSampleRate);
42178c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    break;
42188c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                }
42198c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
422010d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                case OMX_AUDIO_CodingG711:
422110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                {
422210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    OMX_AUDIO_PARAM_PCMMODETYPE params;
422310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    InitOMXParams(&params);
422410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    params.nPortIndex = portIndex;
422510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
4226777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4227777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioPcm, &params, sizeof(params));
4228777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4229777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4230777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
423110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
423210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    const char *mime = NULL;
423310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    if (params.ePCMMode == OMX_AUDIO_PCMModeMULaw) {
423410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_G711_MLAW;
423510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    } else if (params.ePCMMode == OMX_AUDIO_PCMModeALaw) {
423610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_G711_ALAW;
423710d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    } else { // params.ePCMMode == OMX_AUDIO_PCMModeLinear
423810d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_RAW;
423910d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    }
424010d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setString("mime", mime);
424110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setInt32("channel-count", params.nChannels);
424210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setInt32("sample-rate", params.nSamplingRate);
424310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    break;
424410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                }
424541d3f579d2c166984958263533284209b90c87d5Marco Nelissen
424641d3f579d2c166984958263533284209b90c87d5Marco Nelissen                case OMX_AUDIO_CodingGSMFR:
424741d3f579d2c166984958263533284209b90c87d5Marco Nelissen                {
42480806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    OMX_AUDIO_PARAM_PCMMODETYPE params;
424941d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    InitOMXParams(&params);
425041d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    params.nPortIndex = portIndex;
425141d3f579d2c166984958263533284209b90c87d5Marco Nelissen
4252777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4253777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                mNode, OMX_IndexParamAudioPcm, &params, sizeof(params));
4254777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4255777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4256777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
425741d3f579d2c166984958263533284209b90c87d5Marco Nelissen
425841d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MSGSM);
425941d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    notify->setInt32("channel-count", params.nChannels);
42600806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    notify->setInt32("sample-rate", params.nSamplingRate);
426141d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    break;
426210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                }
426310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
4264e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                default:
4265777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGE("Unsupported audio coding: %s(%d)\n",
4266777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            asString(audioDef->eEncoding), audioDef->eEncoding);
4267777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return BAD_TYPE;
4268e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
426931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
427031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
427131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
427231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        default:
4273777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("Unsupported domain: %s(%d)", asString(def.eDomain), def.eDomain);
4274777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return BAD_TYPE;
427531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    }
427631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4277e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    return OK;
4278e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar}
4279e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4280e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarvoid ACodec::sendFormatChange(const sp<AMessage> &reply) {
42814e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    sp<AMessage> notify = mBaseOutputFormat->dup();
4282e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    notify->setInt32("what", kWhatOutputFormatChanged);
4283e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4284777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (getPortFormat(kPortIndexOutput, notify) != OK) {
4285777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("[%s] Failed to get port format to send format change", mComponentName.c_str());
4286777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return;
4287777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
4288e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4289e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    AString mime;
4290e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK(notify->findString("mime", &mime));
4291e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4292e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    int32_t left, top, right, bottom;
4293e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if (mime == MEDIA_MIMETYPE_VIDEO_RAW &&
4294e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        mNativeWindow != NULL &&
4295e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->findRect("crop", &left, &top, &right, &bottom)) {
4296e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        // notify renderer of the crop change
4297e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        // NOTE: native window uses extended right-bottom coordinate
4298e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        reply->setRect("crop", left, top, right + 1, bottom + 1);
4299e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    } else if (mime == MEDIA_MIMETYPE_AUDIO_RAW &&
4300e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar               (mEncoderDelay || mEncoderPadding)) {
4301e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        int32_t channelCount;
4302e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        CHECK(notify->findInt32("channel-count", &channelCount));
4303e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        size_t frameSize = channelCount * sizeof(int16_t);
4304e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        if (mSkipCutBuffer != NULL) {
4305e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            size_t prevbufsize = mSkipCutBuffer->size();
4306e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            if (prevbufsize != 0) {
4307ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                ALOGW("Replacing SkipCutBuffer holding %zu bytes", prevbufsize);
4308e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            }
4309e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        }
4310e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        mSkipCutBuffer = new SkipCutBuffer(
4311e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                mEncoderDelay * frameSize,
4312e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                mEncoderPadding * frameSize);
4313e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
4314e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
431531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->post();
431631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
431731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mSentFormat = true;
431831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber}
431931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
43205778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
4321cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    sp<AMessage> notify = mNotify->dup();
4322d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatError);
4323251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    ALOGE("signalError(omxError %#x, internalError %d)", error, internalError);
4324251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
4325251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (internalError == UNKNOWN_ERROR) { // find better error code
4326251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        const status_t omxStatus = statusFromOMXError(error);
4327251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        if (omxStatus != 0) {
4328251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            internalError = omxStatus;
4329251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        } else {
4330251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            ALOGW("Invalid OMX error %#x", error);
4331251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        }
4332251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
43335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("err", internalError);
4334251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    notify->setInt32("actionCode", ACTION_CODE_FATAL); // could translate from OMX error.
4335cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->post();
4336cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber}
4337cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber
4338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4340eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberACodec::PortDescription::PortDescription() {
4341eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
4342eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4343496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t ACodec::requestIDRFrame() {
4344496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    if (!mIsEncoder) {
4345496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        return ERROR_UNSUPPORTED;
4346496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    }
4347496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4348496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    OMX_CONFIG_INTRAREFRESHVOPTYPE params;
4349496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    InitOMXParams(&params);
4350496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4351496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.nPortIndex = kPortIndexOutput;
4352496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.IntraRefreshVOP = OMX_TRUE;
4353496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4354496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    return mOMX->setConfig(
4355496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            mNode,
4356496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            OMX_IndexConfigVideoIntraVOPRefresh,
4357496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            &params,
4358496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            sizeof(params));
4359496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
4360496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4361eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubervoid ACodec::PortDescription::addBuffer(
4362eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        IOMX::buffer_id id, const sp<ABuffer> &buffer) {
4363eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBufferIDs.push_back(id);
4364eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBuffers.push_back(buffer);
4365eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
4366eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4367eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersize_t ACodec::PortDescription::countBuffers() {
4368eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.size();
4369eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
4370eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4371eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberIOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const {
4372eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.itemAt(index);
4373eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
4374eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4375eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const {
4376eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBuffers.itemAt(index);
4377eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
4378eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4379eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber////////////////////////////////////////////////////////////////////////////////
4380eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4381f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
4382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : AState(parentState),
4383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mCodec(codec) {
4384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4386ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas HuberACodec::BaseState::PortMode ACodec::BaseState::getPortMode(
4387ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
4388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return KEEP_BUFFERS;
4389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4391f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
4392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatInputBufferFilled:
4394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onInputBufferFilled(msg);
4396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatOutputBufferDrained:
4400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onOutputBufferDrained(msg);
4402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatOMXMessage:
4406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXMessage(msg);
4408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
44101dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        case ACodec::kWhatSetSurface:
44111dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        {
44121dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            sp<AReplyToken> replyID;
44131dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            CHECK(msg->senderAwaitsResponse(&replyID));
44141dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
44151dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            sp<RefBase> obj;
44161dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            CHECK(msg->findObject("surface", &obj));
44171dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
4418011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            status_t err =
4419011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                ADebug::isExperimentEnabled("legacy-setsurface") ? BAD_VALUE :
4420011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                        mCodec->handleSetSurface(static_cast<Surface *>(obj.get()));
44211dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
44221dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            sp<AMessage> response = new AMessage;
44231dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            response->setInt32("err", err);
44241dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            response->postReply(replyID);
44251dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            break;
44261dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
44271dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
44287cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
44298f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang        case ACodec::kWhatSetInputSurface:
44307cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
44317cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
4432251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            // This may result in an app illegal state exception.
44337cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            ALOGE("Message 0x%x was not handled", msg->what());
44347cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
44357cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            return true;
44367cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
44377cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4438ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        case ACodec::kWhatOMXDied:
4439ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        {
4440251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            // This will result in kFlagSawMediaServerDie handling in MediaCodec.
4441ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            ALOGE("OMX/mediaserver died, signalling error!");
4442ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT);
4443ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            break;
4444ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        }
4445ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
444630358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        case ACodec::kWhatReleaseCodecInstance:
444730358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        {
444830358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            ALOGI("[%s] forcing the release of codec",
444930358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar                    mCodec->mComponentName.c_str());
445030358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            status_t err = mCodec->mOMX->freeNode(mCodec->mNode);
445130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            ALOGE_IF("[%s] failed to release codec instance: err=%d",
445230358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar                       mCodec->mComponentName.c_str(), err);
445330358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            sp<AMessage> notify = mCodec->mNotify->dup();
445430358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
445530358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            notify->post();
445630358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            break;
445730358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        }
445830358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar
4459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
4461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4466f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
4467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t type;
4468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findInt32("type", &type));
4469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
44705e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // there is a possibility that this is an outstanding message for a
44715e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // codec that we have already destroyed
4472ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    if (mCodec->mNode == 0) {
44735e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar        ALOGI("ignoring message as already freed component: %s",
44745e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar                msg->debugString().c_str());
44755e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar        return true;
44765e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    }
44775e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar
4478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::node_id nodeID;
4479609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("node", (int32_t*)&nodeID));
4480777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (nodeID != mCodec->mNode) {
4481777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("Unexpected message for nodeID: %u, should have been %u", nodeID, mCodec->mNode);
4482777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return false;
4483777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
4484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (type) {
4486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EVENT:
4487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t event, data1, data2;
4489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("event", &event));
4490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data1", &data1));
4491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data2", &data2));
4492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
44930af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            if (event == OMX_EventCmdComplete
44940af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data1 == OMX_CommandFlush
44950af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data2 == (int32_t)OMX_ALL) {
44960af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // Use of this notification is not consistent across
44970af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // implementations. We'll drop this notification and rely
44980af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // on flush-complete notifications on the individual port
44990af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // indices instead.
45000af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
45010af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                return true;
45020af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            }
45030af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
4504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEvent(
4505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_EVENTTYPE>(event),
4506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data1),
4507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data2));
4508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EMPTY_BUFFER_DONE:
4511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
451315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            int32_t fenceFd;
451415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
4515609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
451615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            CHECK(msg->findInt32("fence_fd", &fenceFd));
4517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
451815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            return onOMXEmptyBufferDone(bufferID, fenceFd);
4519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::FILL_BUFFER_DONE:
4522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
4524609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
4525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
452615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            int32_t rangeOffset, rangeLength, flags, fenceFd;
4527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs;
4528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_offset", &rangeOffset));
4530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_length", &rangeLength));
4531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("flags", &flags));
4532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt64("timestamp", &timeUs));
453315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            CHECK(msg->findInt32("fence_fd", &fenceFd));
4534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXFillBufferDone(
4536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    bufferID,
4537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (size_t)rangeOffset, (size_t)rangeLength,
4538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (OMX_U32)flags,
453915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    timeUs,
454015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    fenceFd);
4541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4544777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("Unexpected message type: %d", type);
4545777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return false;
4546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4549f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEvent(
4550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (event != OMX_EventError) {
4552ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        ALOGV("[%s] EVENT(%d, 0x%08x, 0x%08x)",
4553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mCodec->mComponentName.c_str(), event, data1, data2);
4554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return false;
4556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4558ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGE("[%s] ERROR(0x%08x)", mCodec->mComponentName.c_str(), data1);
4559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4560251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // verify OMX component sends back an error we expect.
4561251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    OMX_ERRORTYPE omxError = (OMX_ERRORTYPE)data1;
4562251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (!isOMXError(omxError)) {
4563251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        ALOGW("Invalid OMX error %#x", omxError);
4564251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        omxError = OMX_ErrorUndefined;
4565251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
4566251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    mCodec->signalError(omxError);
4567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
457115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarbool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID, int fenceFd) {
4572ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGV("[%s] onOMXEmptyBufferDone %u",
4573349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber         mCodec->mComponentName.c_str(), bufferID);
4574349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
45750806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
45760806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
45770806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (status != BufferInfo::OWNED_BY_COMPONENT) {
45780806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGE("Wrong ownership in EBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
45790806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->dumpBuffers(kPortIndexInput);
458015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        if (fenceFd >= 0) {
458115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            ::close(fenceFd);
458215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        }
45830806340688c937e7b78c2d89db3809274130df4eLajos Molnar        return false;
45840806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
4585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
4586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
458715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    // input buffers cannot take fences, so wait for any fence now
458815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    (void)mCodec->waitForFence(fenceFd, "onOMXEmptyBufferDone");
458915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    fenceFd = -1;
459015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
459115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    // still save fence for completeness
459215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    info->setWriteFence(fenceFd, "onOMXEmptyBufferDone");
459315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
459496e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // We're in "store-metadata-in-buffers" mode, the underlying
459596e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // OMX component had access to data that's implicitly refcounted
459696e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // by this "MediaBuffer" object. Now that the OMX component has
459796e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // told us that it's done with the input buffer, we can decrement
459896e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // the mediaBuffer's reference count.
459996e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    info->mData->setMediaBufferBase(NULL);
4600d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
4602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            postFillThisBuffer(info);
4609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4611777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        case FREE_BUFFERS:
4612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4613777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("SHOULD NOT REACH HERE: cannot free empty output buffers");
4614777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return false;
4615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4620f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
4621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
4622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
4623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
4626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
4628d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatFillThisBuffer);
4629609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    notify->setInt32("buffer-id", info->mBufferID);
4630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mData->meta()->clear();
46322d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    notify->setBuffer("buffer", info->mData);
4633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
46341d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec);
4635609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    reply->setInt32("buffer-id", info->mBufferID);
4636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setMessage("reply", reply);
4638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->post();
4640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
4642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4644f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
4645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
4646609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
46472d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    sp<ABuffer> buffer;
4648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t err = OK;
46495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool eos = false;
4650a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar    PortMode mode = getPortMode(kPortIndexInput);
46515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
46522d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    if (!msg->findBuffer("buffer", &buffer)) {
4653a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar        /* these are unfilled buffers returned by client */
4654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findInt32("err", &err));
4655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
46567fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        if (err == OK) {
46577fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            /* buffers with no errors are returned on MediaCodec.flush */
46587fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            mode = KEEP_BUFFERS;
46597fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        } else {
46607fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            ALOGV("[%s] saw error %d instead of an input buffer",
46617fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                 mCodec->mComponentName.c_str(), err);
46627fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            eos = true;
46637fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        }
46643831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
46652d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber        buffer.clear();
4666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
46685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
46695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
46705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
46715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = ERROR_END_OF_STREAM;
46725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
46735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
46750806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
46760806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (status != BufferInfo::OWNED_BY_UPSTREAM) {
46770806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGE("Wrong ownership in IBF: %s(%d) buffer #%u", _asString(status), status, bufferID);
46780806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->dumpBuffers(kPortIndexInput);
46790806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
46800806340688c937e7b78c2d89db3809274130df4eLajos Molnar        return;
46810806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
4682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
4684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
46885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (eos) {
4689dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (!mCodec->mPortEOS[kPortIndexInput]) {
4690dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
4691dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mInputEOSResult = err;
4692dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
4693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
46995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
4700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int64_t timeUs;
4701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
4702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
4704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t isCSD;
4706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
4707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
4708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
4709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
47105778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (eos) {
47115778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    flags |= OMX_BUFFERFLAG_EOS;
47125778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
47135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer != info->mData) {
4715ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] Needs to copy input data for buffer %u. (%p != %p)",
4716d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(),
4717d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         bufferID,
4718d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         buffer.get(), info->mData.get());
4719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
47200806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    if (buffer->size() > info->mData->capacity()) {
47210806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        ALOGE("data size (%zu) is greated than buffer capacity (%zu)",
47220806340688c937e7b78c2d89db3809274130df4eLajos Molnar                                buffer->size(),           // this is the data received
47230806340688c937e7b78c2d89db3809274130df4eLajos Molnar                                info->mData->capacity()); // this is out buffer size
47240806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
47250806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        return;
47260806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    }
4727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    memcpy(info->mData->data(), buffer->data(), buffer->size());
4728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
4729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4730078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
4731ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] calling emptyBuffer %u w/ codec specific data",
4732078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID);
47335778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else if (flags & OMX_BUFFERFLAG_EOS) {
4734ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] calling emptyBuffer %u w/ EOS",
47355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str(), bufferID);
4736078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                } else {
4737d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
4738ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGI("[%s] calling emptyBuffer %u w/ time %lld us",
4739ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                         mCodec->mComponentName.c_str(), bufferID, (long long)timeUs);
4740d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#else
4741ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] calling emptyBuffer %u w/ time %lld us",
4742ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                         mCodec->mComponentName.c_str(), bufferID, (long long)timeUs);
4743d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
4744078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                }
4745349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4746d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
4747d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ACodec::BufferStats stats;
4748d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
4749d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mFillBufferDoneTimeUs = -1ll;
4750d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mCodec->mBufferStats.add(timeUs, stats);
4751d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
4752d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4753054219874873b41f1c815552987c10465c34ba2bLajos Molnar                if (mCodec->storingMetadataInDecodedBuffers()) {
4754054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    // try to submit an output buffer for each input buffer
4755054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    PortMode outputMode = getPortMode(kPortIndexOutput);
4756054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4757054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    ALOGV("MetadataBuffersToSubmit=%u portMode=%s",
4758054219874873b41f1c815552987c10465c34ba2bLajos Molnar                            mCodec->mMetadataBuffersToSubmit,
4759054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            (outputMode == FREE_BUFFERS ? "FREE" :
4760054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                             outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
4761054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    if (outputMode == RESUBMIT_BUFFERS) {
4762054219874873b41f1c815552987c10465c34ba2bLajos Molnar                        mCodec->submitOutputMetadataBuffer();
4763054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    }
4764054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                }
476515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->checkReadFence("onInputBufferFilled");
47660806340688c937e7b78c2d89db3809274130df4eLajos Molnar                status_t err2 = mCodec->mOMX->emptyBuffer(
47670806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->mNode,
47680806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    bufferID,
47690806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    0,
47700806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    buffer->size(),
47710806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    flags,
477215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    timeUs,
477315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    info->mFenceFd);
477415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->mFenceFd = -1;
47750806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err2 != OK) {
47760806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err2));
47770806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    return;
47780806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
4779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
47810806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (!eos && err == OK) {
47825778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    getMoreInputDataIfPossible();
47835778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
47840806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGV("[%s] Signalled EOS (%d) on the input port",
47850806340688c937e7b78c2d89db3809274130df4eLajos Molnar                         mCodec->mComponentName.c_str(), err);
47865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
47875778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
47885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mInputEOSResult = err;
47895778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
4790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
47910806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err != OK && err != ERROR_END_OF_STREAM) {
47920806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGV("[%s] Signalling EOS on the input port due to error %d",
4793dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str(), err);
4794dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                } else {
47953856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port",
4796dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str());
4797dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
4798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4799ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                ALOGV("[%s] calling emptyBuffer %u signalling EOS",
4800349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                     mCodec->mComponentName.c_str(), bufferID);
4801349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
480215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->checkReadFence("onInputBufferFilled");
48030806340688c937e7b78c2d89db3809274130df4eLajos Molnar                status_t err2 = mCodec->mOMX->emptyBuffer(
48040806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        mCodec->mNode,
48050806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        bufferID,
48060806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        0,
48070806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        0,
48080806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        OMX_BUFFERFLAG_EOS,
480915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                        0,
481015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                        info->mFenceFd);
481115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->mFenceFd = -1;
48120806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err2 != OK) {
48130806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err2));
48140806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    return;
48150806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
4816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexInput] = true;
4819dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                mCodec->mInputEOSResult = err;
4820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4823625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih
4824777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        case FREE_BUFFERS:
4825777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            break;
4826777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim
4827625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih        default:
4828777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("invalid port mode: %d", mode);
4829625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih            break;
4830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4833f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::getMoreInputDataIfPossible() {
4834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
4835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
4836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *eligible = NULL;
4839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4840f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
4841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
4842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
4844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
4845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // There's already a "read" pending.
4846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
4847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
4849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4850f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_US) {
4851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            eligible = info;
4852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (eligible == NULL) {
4856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
4857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(eligible);
4860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4862f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXFillBufferDone(
4863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferID,
4864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        size_t rangeOffset, size_t rangeLength,
4865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 flags,
486615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        int64_t timeUs,
486715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        int fenceFd) {
4868609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] onOMXFillBufferDone %u time %" PRId64 " us, flags = 0x%08x",
48695778822d86b0337407514b9372562b86edfa91cdAndreas Huber         mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
4870349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
48720806340688c937e7b78c2d89db3809274130df4eLajos Molnar    status_t err= OK;
4873d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4874d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
4875d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    index = mCodec->mBufferStats.indexOfKey(timeUs);
4876d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (index >= 0) {
4877d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
4878d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
4879d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4880d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ALOGI("frame PTS %lld: %lld",
4881d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                timeUs,
4882d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
4883d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4884d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mCodec->mBufferStats.removeItemsAt(index);
4885d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats = NULL;
4886d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
4887d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
4888d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
4890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
48910806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
48920806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (status != BufferInfo::OWNED_BY_COMPONENT) {
48930806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGE("Wrong ownership in FBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
48940806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->dumpBuffers(kPortIndexOutput);
48950806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
489615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        if (fenceFd >= 0) {
489715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            ::close(fenceFd);
489815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        }
48990806340688c937e7b78c2d89db3809274130df4eLajos Molnar        return true;
49000806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
4901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4902054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mDequeuedAt = ++mCodec->mDequeueCounter;
4903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
4904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
490515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    // byte buffers cannot take fences, so wait for any fence now
490615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (mCodec->mNativeWindow == NULL) {
490715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        (void)mCodec->waitForFence(fenceFd, "onOMXFillBufferDone");
490815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        fenceFd = -1;
490915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
491015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    info->setReadFence(fenceFd, "onOMXFillBufferDone");
491115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
4912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
4913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4920a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            if (rangeLength == 0 && (!(flags & OMX_BUFFERFLAG_EOS)
4921a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                    || mCodec->mPortEOS[kPortIndexOutput])) {
4922609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                ALOGV("[%s] calling fillBuffer %u",
49235778822d86b0337407514b9372562b86edfa91cdAndreas Huber                     mCodec->mComponentName.c_str(), info->mBufferID);
4924349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
492515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                err = mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID, info->mFenceFd);
492615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->mFenceFd = -1;
49270806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err != OK) {
49280806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
49290806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    return true;
49300806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
4931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
49325778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
49335778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
49345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
493531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4936577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            sp<AMessage> reply =
49371d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar                new AMessage(kWhatOutputBufferDrained, mCodec);
4938577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
49394bdda35319d5f46efea2089b865c8a64816389cdMarco Nelissen            if (!mCodec->mSentFormat && rangeLength > 0) {
4940577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->sendFormatChange(reply);
49415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
4942054219874873b41f1c815552987c10465c34ba2bLajos Molnar            if (mCodec->usingMetadataOnEncoderOutput()) {
4943054219874873b41f1c815552987c10465c34ba2bLajos Molnar                native_handle_t *handle = NULL;
4944054219874873b41f1c815552987c10465c34ba2bLajos Molnar                VideoGrallocMetadata &grallocMeta = *(VideoGrallocMetadata *)info->mData->data();
4945054219874873b41f1c815552987c10465c34ba2bLajos Molnar                VideoNativeMetadata &nativeMeta = *(VideoNativeMetadata *)info->mData->data();
4946054219874873b41f1c815552987c10465c34ba2bLajos Molnar                if (info->mData->size() >= sizeof(grallocMeta)
4947054219874873b41f1c815552987c10465c34ba2bLajos Molnar                        && grallocMeta.eType == kMetadataBufferTypeGrallocSource) {
4948054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    handle = (native_handle_t *)grallocMeta.hHandle;
4949054219874873b41f1c815552987c10465c34ba2bLajos Molnar                } else if (info->mData->size() >= sizeof(nativeMeta)
4950054219874873b41f1c815552987c10465c34ba2bLajos Molnar                        && nativeMeta.eType == kMetadataBufferTypeANWBuffer) {
4951054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    handle = (native_handle_t *)nativeMeta.pBuffer->handle;
4952054219874873b41f1c815552987c10465c34ba2bLajos Molnar                }
4953308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setPointer("handle", handle);
4954308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeOffset", rangeOffset);
4955308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeLength", rangeLength);
4956308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            } else {
4957308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->setRange(rangeOffset, rangeLength);
4958308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            }
4959496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#if 0
496021ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen            if (mCodec->mNativeWindow == NULL) {
4961496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                if (IsIDR(info->mData)) {
4962496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                    ALOGI("IDR frame");
4963496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                }
49645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
496521ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen#endif
4966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
49678b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            if (mCodec->mSkipCutBuffer != NULL) {
49688b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                mCodec->mSkipCutBuffer->submit(info->mData);
49698b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            }
49705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mData->meta()->setInt64("timeUs", timeUs);
4971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
49725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4973d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatDrainThisBuffer);
4974609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            notify->setInt32("buffer-id", info->mBufferID);
49752d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            notify->setBuffer("buffer", info->mData);
49765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("flags", flags);
4977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4978609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            reply->setInt32("buffer-id", info->mBufferID);
4979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
49805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setMessage("reply", reply);
4981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
49825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->post();
49835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
49845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
4985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (flags & OMX_BUFFERFLAG_EOS) {
49875778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
49885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                sp<AMessage> notify = mCodec->mNotify->dup();
4990d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar                notify->setInt32("what", CodecBase::kWhatEOS);
4991dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                notify->setInt32("err", mCodec->mInputEOSResult);
4992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->post();
4993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexOutput] = true;
4995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4999777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        case FREE_BUFFERS:
50000806340688c937e7b78c2d89db3809274130df4eLajos Molnar            err = mCodec->freeBuffer(kPortIndexOutput, index);
50010806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
50020806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
50030806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
50040806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
5005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5006777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim
5007777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        default:
5008777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("Invalid port mode: %d", mode);
5009777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return false;
5010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
5013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5015f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
5016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
5017609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
5018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
50190806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo *info = mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
50200806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
50210806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (status != BufferInfo::OWNED_BY_DOWNSTREAM) {
50220806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGE("Wrong ownership in OBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
50230806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->dumpBuffers(kPortIndexOutput);
50240806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
50250806340688c937e7b78c2d89db3809274130df4eLajos Molnar        return;
50260806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
5027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5028577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    android_native_rect_t crop;
5029777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (msg->findRect("crop", &crop.left, &crop.top, &crop.right, &crop.bottom)) {
5030777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        status_t err = native_window_set_crop(mCodec->mNativeWindow.get(), &crop);
5031777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGW_IF(err != NO_ERROR, "failed to set crop: %d", err);
5032577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    }
5033577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
5034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t render;
5035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mNativeWindow != NULL
50366aade6058521b0dbd35a9a4620f4d04f02f90444Marco Nelissen            && msg->findInt32("render", &render) && render != 0
503779ee2399b67c7a11042c5904dc1309712a76f8cbJianzheng Zhou            && info->mData != NULL && info->mData->size() != 0) {
50386fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        ATRACE_NAME("render");
5039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The client wants this buffer to be rendered.
5040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5041fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        int64_t timestampNs = 0;
5042fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        if (!msg->findInt64("timestampNs", &timestampNs)) {
5043fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // TODO: it seems like we should use the timestamp
5044fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // in the (media)buffer as it potentially came from
5045fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // an input surface, but we did not propagate it prior to
5046fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // API 20.  Perhaps check for target SDK version.
5047fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#if 0
5048fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            if (info->mData->meta()->findInt64("timeUs", &timestampNs)) {
504947aea1f7c58f5302b16822f9e7e1763f2af04ef5Lajos Molnar                ALOGV("using buffer PTS of %" PRId64, timestampNs);
5050fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar                timestampNs *= 1000;
5051fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            }
5052fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#endif
5053fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
5054fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
50555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err;
5056fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        err = native_window_set_buffers_timestamp(mCodec->mNativeWindow.get(), timestampNs);
50570806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGW_IF(err != NO_ERROR, "failed to set buffer timestamp: %d", err);
5058fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
505915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info->checkReadFence("onOutputBufferDrained before queueBuffer");
50600806340688c937e7b78c2d89db3809274130df4eLajos Molnar        err = mCodec->mNativeWindow->queueBuffer(
506115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    mCodec->mNativeWindow.get(), info->mGraphicBuffer.get(), info->mFenceFd);
506215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info->mFenceFd = -1;
50630806340688c937e7b78c2d89db3809274130df4eLajos Molnar        if (err == OK) {
5064cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
5065cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        } else {
5066251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5067cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
506815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            // keeping read fence as write fence to avoid clobbering
506915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            info->mIsReadFence = false;
5070cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        }
5071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
50726fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        if (mCodec->mNativeWindow != NULL &&
50736fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar            (info->mData == NULL || info->mData->size() != 0)) {
507415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            // move read fence into write fence to avoid clobbering
507515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            info->mIsReadFence = false;
50766fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar            ATRACE_NAME("frame-drop");
50776fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        }
5078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_US;
5079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5081f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
5082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
5084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
5085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5086f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
5087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
5089f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // We cannot resubmit the buffer we just rendered, dequeue
5090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // the spare instead.
5091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info = mCodec->dequeueBufferFromNativeWindow();
5093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5094f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5095f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
5098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (!mCodec->mPortEOS[kPortIndexOutput]) {
5100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
5101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // We cannot resubmit the buffer we just rendered, dequeue
5102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // the spare instead.
5103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info = mCodec->dequeueBufferFromNativeWindow();
5105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
5106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5107c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                if (info != NULL) {
5108609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                    ALOGV("[%s] calling fillBuffer %u",
5109c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                         mCodec->mComponentName.c_str(), info->mBufferID);
511015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    info->checkWriteFence("onOutputBufferDrained::RESUBMIT_BUFFERS");
511115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    status_t err = mCodec->mOMX->fillBuffer(
511215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                            mCodec->mNode, info->mBufferID, info->mFenceFd);
511315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    info->mFenceFd = -1;
51140806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    if (err == OK) {
51150806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
51160806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    } else {
51170806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
51180806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    }
5119c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                }
5120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5124777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        case FREE_BUFFERS:
5125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
51260806340688c937e7b78c2d89db3809274130df4eLajos Molnar            status_t err = mCodec->freeBuffer(kPortIndexOutput, index);
51270806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
51280806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
51290806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
5130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5132777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim
5133777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        default:
5134777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("Invalid port mode: %d", mode);
5135777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return;
5136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5141f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::UninitializedState::UninitializedState(ACodec *codec)
5142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5145c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::UninitializedState::stateEntered() {
5146c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("Now uninitialized");
5147ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
5148ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (mDeathNotifier != NULL) {
5149f888020c6e2735624f2b2a30e72aca24e17b8b4dMarco Nelissen        IInterface::asBinder(mCodec->mOMX)->unlinkToDeath(mDeathNotifier);
5150ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
5151ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
5152ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
5153ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNativeWindow.clear();
5154ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    mCodec->mNode = 0;
5155ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mOMX.clear();
5156ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mQuirks = 0;
5157ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mFlags = 0;
5158054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mCodec->mInputMetadataType = kMetadataBufferTypeInvalid;
5159054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mCodec->mOutputMetadataType = kMetadataBufferTypeInvalid;
5160ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mComponentName.clear();
5161c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
5162c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5163f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
5164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatSetup:
5168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onSetup(msg);
5170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
51755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case ACodec::kWhatAllocateComponent:
51765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
51775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            onAllocateComponent(msg);
51785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            handled = true;
51795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
51805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
51815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatShutdown:
5183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5184c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
5185c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
5186c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
518754b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            ALOGW_IF(keepComponentAllocated,
518854b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar                     "cannot keep component allocated on shutdown in Uninitialized state");
5189c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
5191d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
5192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
5193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5195c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
5196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatFlush:
5199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
5201d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
5202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
5203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5205c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
5206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
520830358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        case ACodec::kWhatReleaseCodecInstance:
520930358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        {
521030358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            // nothing to do, as we have already signaled shutdown
521130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            handled = true;
521230358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            break;
521330358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        }
521430358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar
5215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
5217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5222f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::UninitializedState::onSetup(
5223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
5224c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (onAllocateComponent(msg)
5225c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            && mCodec->mLoadedState->onConfigureComponent(msg)) {
5226c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mLoadedState->onStart();
5227c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
52285778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
52295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5230c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
52315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onAllocateComponent");
52325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5233ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    CHECK(mCodec->mNode == 0);
52345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMXClient client;
523648a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung    if (client.connect() != OK) {
523748a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung        mCodec->signalError(OMX_ErrorUndefined, NO_INIT);
523848a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung        return false;
523948a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung    }
5240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<IOMX> omx = client.interface();
5242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
52431d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec);
5244ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
5245ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mDeathNotifier = new DeathNotifier(notify);
5246f888020c6e2735624f2b2a30e72aca24e17b8b4dMarco Nelissen    if (IInterface::asBinder(omx)->linkToDeath(mDeathNotifier) != OK) {
5247ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // This was a local binder, if it dies so do we, we won't care
5248ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // about any notifications in the afterlife.
5249ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
5250ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
5251ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
5252e671207115fac3914134c61b336d5fa0242c68caAndreas Huber    Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs;
52535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    AString mime;
5255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
52565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString componentName;
5257d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint32_t quirks = 0;
52587791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen    int32_t encoder = false;
52595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findString("componentName", &componentName)) {
5260e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        ssize_t index = matchingCodecs.add();
5261e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        OMXCodec::CodecNameAndQuirks *entry = &matchingCodecs.editItemAt(index);
5262e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        entry->mName = String8(componentName.c_str());
5263afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
5264e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        if (!OMXCodec::findCodecQuirks(
5265e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                    componentName.c_str(), &entry->mQuirks)) {
5266e671207115fac3914134c61b336d5fa0242c68caAndreas Huber            entry->mQuirks = 0;
5267afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
52685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
52695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(msg->findString("mime", &mime));
52705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
52715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("encoder", &encoder)) {
52725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder = false;
52735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
52745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
52755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMXCodec::findMatchingCodecs(
52765778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mime.c_str(),
52775778822d86b0337407514b9372562b86edfa91cdAndreas Huber                encoder, // createEncoder
52785778822d86b0337407514b9372562b86edfa91cdAndreas Huber                NULL,  // matchComponentName
52795778822d86b0337407514b9372562b86edfa91cdAndreas Huber                0,     // flags
5280e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                &matchingCodecs);
52815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
52821065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
52831065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    sp<CodecObserver> observer = new CodecObserver;
5284ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    IOMX::node_id node = 0;
52851065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
5286201d8d400eb037547f4f476a838475b13a446007Wei Jia    status_t err = NAME_NOT_FOUND;
52871065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
52881065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            ++matchIndex) {
5289e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        componentName = matchingCodecs.itemAt(matchIndex).mName.string();
5290e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        quirks = matchingCodecs.itemAt(matchIndex).mQuirks;
5291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5292da153975581fb3161a30452348a5b26ee72d9255Elliott Hughes        pid_t tid = gettid();
5293078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        int prevPriority = androidGetThreadPriority(tid);
5294078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
52959f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu        err = omx->allocateNode(componentName.c_str(), observer, &node);
5296078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, prevPriority);
5297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
52981065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        if (err == OK) {
52991065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            break;
53007a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He        } else {
53017a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He            ALOGW("Allocating component '%s' failed, try next one.", componentName.c_str());
53021065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
53031065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
5304ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        node = 0;
53051065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    }
53061065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
5307ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    if (node == 0) {
53085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!mime.empty()) {
53099f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu            ALOGE("Unable to instantiate a %scoder for type '%s' with err %#x.",
53109f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu                    encoder ? "en" : "de", mime.c_str(), err);
53115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
53129f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu            ALOGE("Unable to instantiate codec '%s' with err %#x.", componentName.c_str(), err);
53135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
5314c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
531552e88b2986536e83a7a6da63461556b8734a85f3Ronghua Wu        mCodec->signalError((OMX_ERRORTYPE)err, makeNoSideEffectStatus(err));
5316c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
5317c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
5318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
53191d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    notify = new AMessage(kWhatOMXMessage, mCodec);
5320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    observer->setNotificationMessage(notify);
5321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mComponentName = componentName;
5323ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    mCodec->mFlags = 0;
5324ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
5325ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (componentName.endsWith(".secure")) {
5326ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        mCodec->mFlags |= kFlagIsSecure;
53271713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        mCodec->mFlags |= kFlagIsGrallocUsageProtected;
53280167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
5329ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
5330ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
5331afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mCodec->mQuirks = quirks;
5332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mOMX = omx;
5333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mNode = node;
5334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
53355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
53365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
5337d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatComponentAllocated);
53385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setString("componentName", mCodec->mComponentName.c_str());
53395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
53405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5341c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5342c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mCodec->changeState(mCodec->mLoadedState);
5343c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5344c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
53455778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
53465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5347c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
5348c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5349c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas HuberACodec::LoadedState::LoadedState(ACodec *codec)
5350c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    : BaseState(codec) {
5351c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
5352c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5353c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::stateEntered() {
5354c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
5355c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5356f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mPortEOS[kPortIndexInput] =
5357f6f38287b97ec69b169387add6458f859b770e65Andreas Huber        mCodec->mPortEOS[kPortIndexOutput] = false;
5358f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
5359f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mInputEOSResult = OK;
5360f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
5361054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mDequeueCounter = 0;
5362054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mCodec->mMetadataBuffersToSubmit = 0;
5363a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    mCodec->mRepeatFrameDelayUs = -1ll;
5364e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mInputFormat.clear();
5365e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mOutputFormat.clear();
53664e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    mCodec->mBaseOutputFormat.clear();
5367054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5368c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (mCodec->mShutdownInProgress) {
5369c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
5370c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5371c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mShutdownInProgress = false;
5372c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mKeepComponentAllocated = false;
5373c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5374c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        onShutdown(keepComponentAllocated);
5375c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
537654b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    mCodec->mExplicitShutdown = false;
5377f393c33e65ae51a7cf168b4e15771b152f996b32Wei Jia
5378f393c33e65ae51a7cf168b4e15771b152f996b32Wei Jia    mCodec->processDeferredMessages();
5379c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
5380c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5381c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
5382c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (!keepComponentAllocated) {
53830806340688c937e7b78c2d89db3809274130df4eLajos Molnar        (void)mCodec->mOMX->freeNode(mCodec->mNode);
5384c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5385c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->changeState(mCodec->mUninitializedState);
5386c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
5387c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
538854b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    if (mCodec->mExplicitShutdown) {
538954b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        sp<AMessage> notify = mCodec->mNotify->dup();
5390d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
539154b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        notify->post();
539254b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        mCodec->mExplicitShutdown = false;
539354b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    }
5394c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
5395c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5396c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
5397c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool handled = false;
5398c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5399c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    switch (msg->what()) {
5400c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatConfigureComponent:
5401c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
5402c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onConfigureComponent(msg);
5403c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
5404c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
5405c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
5406c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
54077cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
54087cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
54097cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            onCreateInputSurface(msg);
54107cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
54117cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
54127cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
54137cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
54148f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang        case ACodec::kWhatSetInputSurface:
5415d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        {
54168f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang            onSetInputSurface(msg);
5417d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            handled = true;
5418d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            break;
5419d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        }
5420d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5421c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatStart:
5422c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
5423c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onStart();
5424c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
5425c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
5426c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
5427c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5428c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatShutdown:
5429c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
5430c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
5431c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
5432c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
5433c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
543454b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
5435c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onShutdown(keepComponentAllocated);
5436c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5437c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
5438c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
5439c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
5440c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5441c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatFlush:
5442c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
5443c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
5444d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
5445c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->post();
5446c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5447c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
5448c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
5449c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
5450c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5451c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        default:
5452c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            return BaseState::onMessageReceived(msg);
5453c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
5454c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5455c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return handled;
5456c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
5457c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5458c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onConfigureComponent(
54595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg) {
54605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onConfigureComponent");
54615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5462ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    CHECK(mCodec->mNode != 0);
54635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
54640806340688c937e7b78c2d89db3809274130df4eLajos Molnar    status_t err = OK;
54655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString mime;
54660806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (!msg->findString("mime", &mime)) {
54670806340688c937e7b78c2d89db3809274130df4eLajos Molnar        err = BAD_VALUE;
54680806340688c937e7b78c2d89db3809274130df4eLajos Molnar    } else {
54690806340688c937e7b78c2d89db3809274130df4eLajos Molnar        err = mCodec->configureCodec(mime.c_str(), msg);
54700806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
54715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
5472c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        ALOGE("[%s] configureCodec returning error %d",
5473c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber              mCodec->mComponentName.c_str(), err);
5474c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber
5475251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5476c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
54775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
54795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
54805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
5481d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatComponentConfigured);
5482e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("input-format", mCodec->mInputFormat);
5483e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("output-format", mCodec->mOutputFormat);
54845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
54855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5486c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5487c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
54885778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
54895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5490d291c222357303b9611cab89d0c3b047584ef377Chong Zhangstatus_t ACodec::LoadedState::setupInputSurface() {
5491d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    status_t err = OK;
5492a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
5493d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mRepeatFrameDelayUs > 0ll) {
5494a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        err = mCodec->mOMX->setInternalOption(
5495a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                mCodec->mNode,
5496a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                kPortIndexInput,
5497a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY,
5498a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                &mCodec->mRepeatFrameDelayUs,
5499a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                sizeof(mCodec->mRepeatFrameDelayUs));
5500a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
5501a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (err != OK) {
5502a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            ALOGE("[%s] Unable to configure option to repeat previous "
5503a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  "frames (err %d)",
5504a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  mCodec->mComponentName.c_str(),
5505a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  err);
5506d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
5507a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
5508a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
5509a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
5510d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mMaxPtsGapUs > 0ll) {
551194ee4b708acfa941581160b267afb79192b1d816Chong Zhang        err = mCodec->mOMX->setInternalOption(
551294ee4b708acfa941581160b267afb79192b1d816Chong Zhang                mCodec->mNode,
551394ee4b708acfa941581160b267afb79192b1d816Chong Zhang                kPortIndexInput,
551494ee4b708acfa941581160b267afb79192b1d816Chong Zhang                IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP,
551594ee4b708acfa941581160b267afb79192b1d816Chong Zhang                &mCodec->mMaxPtsGapUs,
551694ee4b708acfa941581160b267afb79192b1d816Chong Zhang                sizeof(mCodec->mMaxPtsGapUs));
551794ee4b708acfa941581160b267afb79192b1d816Chong Zhang
551894ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (err != OK) {
551994ee4b708acfa941581160b267afb79192b1d816Chong Zhang            ALOGE("[%s] Unable to configure max timestamp gap (err %d)",
552072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    mCodec->mComponentName.c_str(),
552172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    err);
5522d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
55232c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
55242c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
55252c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
5526d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mMaxFps > 0) {
552737b2b389139ed638831e49708c947863eef631efRonghua Wu        err = mCodec->mOMX->setInternalOption(
552837b2b389139ed638831e49708c947863eef631efRonghua Wu                mCodec->mNode,
552937b2b389139ed638831e49708c947863eef631efRonghua Wu                kPortIndexInput,
553037b2b389139ed638831e49708c947863eef631efRonghua Wu                IOMX::INTERNAL_OPTION_MAX_FPS,
553137b2b389139ed638831e49708c947863eef631efRonghua Wu                &mCodec->mMaxFps,
553237b2b389139ed638831e49708c947863eef631efRonghua Wu                sizeof(mCodec->mMaxFps));
553337b2b389139ed638831e49708c947863eef631efRonghua Wu
553437b2b389139ed638831e49708c947863eef631efRonghua Wu        if (err != OK) {
553537b2b389139ed638831e49708c947863eef631efRonghua Wu            ALOGE("[%s] Unable to configure max fps (err %d)",
553637b2b389139ed638831e49708c947863eef631efRonghua Wu                    mCodec->mComponentName.c_str(),
553737b2b389139ed638831e49708c947863eef631efRonghua Wu                    err);
5538d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
553937b2b389139ed638831e49708c947863eef631efRonghua Wu        }
554037b2b389139ed638831e49708c947863eef631efRonghua Wu    }
554137b2b389139ed638831e49708c947863eef631efRonghua Wu
5542d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mTimePerCaptureUs > 0ll
55432c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            && mCodec->mTimePerFrameUs > 0ll) {
55442c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        int64_t timeLapse[2];
55452c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[0] = mCodec->mTimePerFrameUs;
55462c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[1] = mCodec->mTimePerCaptureUs;
55472c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        err = mCodec->mOMX->setInternalOption(
55482c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                mCodec->mNode,
55492c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                kPortIndexInput,
55502c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                IOMX::INTERNAL_OPTION_TIME_LAPSE,
55512c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                &timeLapse[0],
55522c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                sizeof(timeLapse));
55532c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
55542c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (err != OK) {
55552c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            ALOGE("[%s] Unable to configure time lapse (err %d)",
55562c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    mCodec->mComponentName.c_str(),
55572c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    err);
5558d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
55592c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
55602c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
556172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
5562d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mCreateInputBuffersSuspended) {
556372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        bool suspend = true;
556472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        err = mCodec->mOMX->setInternalOption(
556572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                mCodec->mNode,
556672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                kPortIndexInput,
556772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                IOMX::INTERNAL_OPTION_SUSPEND,
556872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                &suspend,
556972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                sizeof(suspend));
557072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
557172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
557272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("[%s] Unable to configure option to suspend (err %d)",
557394ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  mCodec->mComponentName.c_str(),
557494ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  err);
5575d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
557694ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
557794ee4b708acfa941581160b267afb79192b1d816Chong Zhang    }
557894ee4b708acfa941581160b267afb79192b1d816Chong Zhang
5579d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    return OK;
5580d291c222357303b9611cab89d0c3b047584ef377Chong Zhang}
5581d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5582d291c222357303b9611cab89d0c3b047584ef377Chong Zhangvoid ACodec::LoadedState::onCreateInputSurface(
5583d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        const sp<AMessage> & /* msg */) {
5584d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    ALOGV("onCreateInputSurface");
5585d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5586d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<AMessage> notify = mCodec->mNotify->dup();
5587d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    notify->setInt32("what", CodecBase::kWhatInputSurfaceCreated);
5588d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5589d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<IGraphicBufferProducer> bufferProducer;
5590d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    status_t err = mCodec->mOMX->createInputSurface(
5591054219874873b41f1c815552987c10465c34ba2bLajos Molnar            mCodec->mNode, kPortIndexInput, &bufferProducer, &mCodec->mInputMetadataType);
5592d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5593d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (err == OK) {
5594d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        err = setupInputSurface();
5595d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    }
5596d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
55977cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err == OK) {
55987cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setObject("input-surface",
55997cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                new BufferProducerWrapper(bufferProducer));
56007cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else {
56017cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // Can't use mCodec->signalError() here -- MediaCodec won't forward
56027cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // the error through because it's in the "configured" state.  We
56037cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // send a kWhatInputSurfaceCreated with an error value instead.
56047cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGE("[%s] onCreateInputSurface returning error %d",
56057cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                mCodec->mComponentName.c_str(), err);
56067cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setInt32("err", err);
56077cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
56087cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->post();
56097cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
56107cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
56118f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhangvoid ACodec::LoadedState::onSetInputSurface(
5612d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        const sp<AMessage> &msg) {
56138f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang    ALOGV("onSetInputSurface");
5614d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5615d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<AMessage> notify = mCodec->mNotify->dup();
5616d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    notify->setInt32("what", CodecBase::kWhatInputSurfaceAccepted);
5617d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5618d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<RefBase> obj;
5619d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    CHECK(msg->findObject("input-surface", &obj));
5620d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<PersistentSurface> surface = static_cast<PersistentSurface *>(obj.get());
5621d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
56228f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang    status_t err = mCodec->mOMX->setInputSurface(
5623054219874873b41f1c815552987c10465c34ba2bLajos Molnar            mCodec->mNode, kPortIndexInput, surface->getBufferConsumer(),
5624054219874873b41f1c815552987c10465c34ba2bLajos Molnar            &mCodec->mInputMetadataType);
5625d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5626d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (err == OK) {
5627d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        err = setupInputSurface();
5628d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    }
5629d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5630d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (err != OK) {
5631d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        // Can't use mCodec->signalError() here -- MediaCodec won't forward
5632d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        // the error through because it's in the "configured" state.  We
5633d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        // send a kWhatInputSurfaceAccepted with an error value instead.
56348f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang        ALOGE("[%s] onSetInputSurface returning error %d",
5635d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                mCodec->mComponentName.c_str(), err);
5636d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        notify->setInt32("err", err);
5637d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    }
5638d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    notify->post();
5639d291c222357303b9611cab89d0c3b047584ef377Chong Zhang}
5640d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5641c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onStart() {
56425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onStart");
56435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
56440806340688c937e7b78c2d89db3809274130df4eLajos Molnar    status_t err = mCodec->mOMX->sendCommand(mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle);
56450806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (err != OK) {
56460806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
56470806340688c937e7b78c2d89db3809274130df4eLajos Molnar    } else {
56480806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->changeState(mCodec->mLoadedToIdleState);
56490806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
5650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5654f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
5655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5658f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::LoadedToIdleState::stateEntered() {
56593856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
5660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5661cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    status_t err;
5662cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    if ((err = allocateBuffers()) != OK) {
566329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to allocate buffers after transitioning to IDLE state "
5664cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             "(error 0x%08x)",
5665cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             err);
5666cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
5667251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
566891bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber
566991bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber        mCodec->changeState(mCodec->mLoadedState);
5670cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    }
5671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5673f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::LoadedToIdleState::allocateBuffers() {
5674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
5675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
5677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
5678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mCodec->allocateBuffersOnPort(kPortIndexOutput);
5681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5683f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
5684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
568572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
5686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
5689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
56926507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
56936507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
56946507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
56956507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
56966507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
56976507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
56986463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatResume:
56996463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
57006463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We'll be active soon enough.
57016463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
57026463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
57036463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
57046463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatFlush:
57056463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
57066463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We haven't even started yet, so we're flushed alright...
57076463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            sp<AMessage> notify = mCodec->mNotify->dup();
5708d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
57096463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->post();
57106463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
57116463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
57126463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
5713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
5715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5718f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onOMXEvent(
5719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
57230806340688c937e7b78c2d89db3809274130df4eLajos Molnar            status_t err = OK;
57240806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandStateSet
57250806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    || data2 != (OMX_U32)OMX_StateIdle) {
57260806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("Unexpected command completion in LoadedToIdleState: %s(%u) %s(%u)",
57270806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1,
57280806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_STATETYPE)data2), data2);
57290806340688c937e7b78c2d89db3809274130df4eLajos Molnar                err = FAILED_TRANSACTION;
57300806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
5731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
57320806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err == OK) {
57330806340688c937e7b78c2d89db3809274130df4eLajos Molnar                err = mCodec->mOMX->sendCommand(
57340806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting);
57350806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
5736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
57370806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
57380806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
57390806340688c937e7b78c2d89db3809274130df4eLajos Molnar            } else {
57400806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->changeState(mCodec->mIdleToExecutingState);
57410806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
5742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5753f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
5754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5757f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToExecutingState::stateEntered() {
57583856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
5759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5761f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
5762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
576372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
5764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
5767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5770d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatResume:
5771d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
5772d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We'll be active soon enough.
5773d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
5774d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
5775d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
5776d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatFlush:
5777d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
5778d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We haven't even started yet, so we're flushed alright...
5779d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
5780d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
5781d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->post();
5782d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
5783d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
5784d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
5785d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
57866507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
57876507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
57886507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
57896507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
57906507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
57916507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
5792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
5794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5797f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onOMXEvent(
5798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
58020806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandStateSet
58030806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    || data2 != (OMX_U32)OMX_StateExecuting) {
58040806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("Unexpected command completion in IdleToExecutingState: %s(%u) %s(%u)",
58050806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1,
58060806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_STATETYPE)data2), data2);
58070806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
58080806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
58090806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
5810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mExecutingState->resume();
5812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingState);
5813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5824f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingState::ExecutingState(ACodec *codec)
5825349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    : BaseState(codec),
5826349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber      mActive(false) {
5827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5829f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
5830ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
5831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
5832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5834054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputMetaBuffers() {
5835054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // submit as many buffers as there are input buffers with the codec
5836054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // in case we are in port reconfiguring
5837054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
5838054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
5839054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5840054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) {
5841054219874873b41f1c815552987c10465c34ba2bLajos Molnar            if (mCodec->submitOutputMetadataBuffer() != OK)
5842054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                break;
5843054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
5844054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
58454dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
58464dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
5847054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mCodec->signalSubmitOutputMetadataBufferIfEOS_workaround();
5848054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
5849054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5850054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitRegularOutputBuffers() {
58510806340688c937e7b78c2d89db3809274130df4eLajos Molnar    bool failed = false;
5852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
5853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
5854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mCodec->mNativeWindow != NULL) {
58560806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (info->mStatus != BufferInfo::OWNED_BY_US
58570806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
58580806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("buffers should be owned by us or the surface");
58590806340688c937e7b78c2d89db3809274130df4eLajos Molnar                failed = true;
58600806340688c937e7b78c2d89db3809274130df4eLajos Molnar                break;
58610806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
5862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
5864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                continue;
5865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
58670806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (info->mStatus != BufferInfo::OWNED_BY_US) {
58680806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("buffers should be owned by us");
58690806340688c937e7b78c2d89db3809274130df4eLajos Molnar                failed = true;
58700806340688c937e7b78c2d89db3809274130df4eLajos Molnar                break;
58710806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
5872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
58740806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGV("[%s] calling fillBuffer %u", mCodec->mComponentName.c_str(), info->mBufferID);
5875349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
587615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info->checkWriteFence("submitRegularOutputBuffers");
587715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        status_t err = mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID, info->mFenceFd);
587815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info->mFenceFd = -1;
58790806340688c937e7b78c2d89db3809274130df4eLajos Molnar        if (err != OK) {
58800806340688c937e7b78c2d89db3809274130df4eLajos Molnar            failed = true;
58810806340688c937e7b78c2d89db3809274130df4eLajos Molnar            break;
58820806340688c937e7b78c2d89db3809274130df4eLajos Molnar        }
5883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
5885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
58860806340688c937e7b78c2d89db3809274130df4eLajos Molnar
58870806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (failed) {
58880806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
58890806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
5890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5892054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputBuffers() {
5893c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar    submitRegularOutputBuffers();
5894054219874873b41f1c815552987c10465c34ba2bLajos Molnar    if (mCodec->storingMetadataInDecodedBuffers()) {
5895054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        submitOutputMetaBuffers();
5896054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
5897054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
5898054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5899f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::resume() {
5900349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    if (mActive) {
59010806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGV("[%s] We're already active, no need to resume.", mCodec->mComponentName.c_str());
5902349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        return;
5903349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    }
5904349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    submitOutputBuffers();
5906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
59073cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    // Post all available input buffers
5908777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (mCodec->mBuffers[kPortIndexInput].size() == 0u) {
5909777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGW("[%s] we don't have any input buffers to resume", mCodec->mComponentName.c_str());
5910777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
5911777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim
59123cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); i++) {
59133cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
59143cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_US) {
59153cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar            postFillThisBuffer(info);
59163cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        }
59173cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    }
5918349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5919349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    mActive = true;
5920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5922f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::stateEntered() {
59233856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
5924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->processDeferredMessages();
5926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5928f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
5929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5934c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
5935c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
5936c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
5937c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5938c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mShutdownInProgress = true;
593954b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
5940c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mKeepComponentAllocated = keepComponentAllocated;
5941c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5942349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
5943349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
59440806340688c937e7b78c2d89db3809274130df4eLajos Molnar            status_t err = mCodec->mOMX->sendCommand(
59450806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle);
59460806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
59470806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (keepComponentAllocated) {
59480806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
59490806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
59500806340688c937e7b78c2d89db3809274130df4eLajos Molnar                // TODO: do some recovery here.
59510806340688c937e7b78c2d89db3809274130df4eLajos Molnar            } else {
59520806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->changeState(mCodec->mExecutingToIdleState);
59530806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
5954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
59617a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong            ALOGV("[%s] ExecutingState flushing now "
5962ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                 "(codec owns %zu/%zu input, %zu/%zu output).",
5963d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mComponentName.c_str(),
5964d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
5965d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexInput].size(),
5966d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
5967d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexOutput].size());
5968d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
5969349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
5970349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
59710806340688c937e7b78c2d89db3809274130df4eLajos Molnar            status_t err = mCodec->mOMX->sendCommand(mCodec->mNode, OMX_CommandFlush, OMX_ALL);
59720806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
59730806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
59740806340688c937e7b78c2d89db3809274130df4eLajos Molnar            } else {
59750806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->changeState(mCodec->mFlushingState);
59760806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
5977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatResume:
5983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            resume();
5985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5990496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
5991496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
5992496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            status_t err = mCodec->requestIDRFrame();
5993496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            if (err != OK) {
5994496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                ALOGW("Requesting an IDR frame failed.");
5995496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            }
5996496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5997496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            handled = true;
5998496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
5999496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
6000496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
6001a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
6002a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
6003a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
6004a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
6005a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
6006a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = mCodec->setParameters(params);
6007a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
6008a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> reply;
6009a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            if (msg->findMessage("reply", &reply)) {
6010a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->setInt32("err", err);
6011a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->post();
6012a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            }
6013a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
6014a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            handled = true;
6015a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
6016a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
6017a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
60187cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
60197cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
60206507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
60217cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
60227cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
60237cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
60247cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
60254dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
6026054219874873b41f1c815552987c10465c34ba2bLajos Molnar        case kWhatSubmitOutputMetadataBufferIfEOS:
60274dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        {
60284dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            if (mCodec->mPortEOS[kPortIndexInput] &&
60294dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    !mCodec->mPortEOS[kPortIndexOutput]) {
6030054219874873b41f1c815552987c10465c34ba2bLajos Molnar                status_t err = mCodec->submitOutputMetadataBuffer();
60314dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                if (err == OK) {
6032054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    mCodec->signalSubmitOutputMetadataBufferIfEOS_workaround();
60334dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                }
60344dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            }
60354dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            return true;
60364dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        }
60374dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
6038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
6040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
6044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6046a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t ACodec::setParameters(const sp<AMessage> &params) {
6047a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    int32_t videoBitrate;
6048530fdbdc1b5491f3fbf172752834d1515701e142Lajos Molnar    if (params->findInt32("video-bitrate", &videoBitrate)) {
6049a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        OMX_VIDEO_CONFIG_BITRATETYPE configParams;
6050a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        InitOMXParams(&configParams);
6051a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nPortIndex = kPortIndexOutput;
6052a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nEncodeBitrate = videoBitrate;
6053a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
6054a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        status_t err = mOMX->setConfig(
6055a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                mNode,
6056a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                OMX_IndexConfigVideoBitrate,
6057a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                &configParams,
6058a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                sizeof(configParams));
6059a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
6060a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        if (err != OK) {
6061a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
6062a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                   videoBitrate, err);
6063a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
6064a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            return err;
6065a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
6066a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    }
6067a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
606872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    int64_t skipFramesBeforeUs;
606972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (params->findInt64("skip-frames-before", &skipFramesBeforeUs)) {
607072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        status_t err =
607172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mOMX->setInternalOption(
607272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     mNode,
607372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     kPortIndexInput,
607472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     IOMX::INTERNAL_OPTION_START_TIME,
607572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     &skipFramesBeforeUs,
607672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     sizeof(skipFramesBeforeUs));
607772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
607872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
607972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("Failed to set parameter 'skip-frames-before' (err %d)", err);
608072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            return err;
608172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
608272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
608372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
6084e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    int32_t dropInputFrames;
6085e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    if (params->findInt32("drop-input-frames", &dropInputFrames)) {
6086e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        bool suspend = dropInputFrames != 0;
6087e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
6088b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err =
6089b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            mOMX->setInternalOption(
6090e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     mNode,
6091e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     kPortIndexInput,
6092e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     IOMX::INTERNAL_OPTION_SUSPEND,
6093e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     &suspend,
6094b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber                     sizeof(suspend));
6095b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
6096b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
6097b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err);
6098b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
6099b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
6100b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    }
6101b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
6102b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    int32_t dummy;
6103b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    if (params->findInt32("request-sync", &dummy)) {
6104b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err = requestIDRFrame();
6105b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
6106b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
6107b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Requesting a sync frame failed w/ err %d", err);
6108b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
6109b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
6110e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    }
6111e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
61128db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    float rate;
61138db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    if (params->findFloat("operating-rate", &rate) && rate > 0) {
61148db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        status_t err = setOperatingRate(rate, mIsVideo);
61158db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        if (err != OK) {
61168db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu            ALOGE("Failed to set parameter 'operating-rate' (err %d)", err);
61178db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu            return err;
61188db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        }
61198db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    }
61208db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu
6121a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return OK;
6122a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
6123a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
61246507d14c6d10f93d390de62b9eed267f9b544985Andy McFaddenvoid ACodec::onSignalEndOfInputStream() {
61256507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    sp<AMessage> notify = mNotify->dup();
6126d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatSignaledInputEOS);
61276507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
61286507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    status_t err = mOMX->signalEndOfInputStream(mNode);
61296507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    if (err != OK) {
61306507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        notify->setInt32("err", err);
61316507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    }
61326507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->post();
61336507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden}
61346507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
6135f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onOMXEvent(
6136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
6138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventPortSettingsChanged:
6139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
6141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
614231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
6143054219874873b41f1c815552987c10465c34ba2bLajos Molnar                mCodec->mMetadataBuffersToSubmit = 0;
6144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
6145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
6146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_CommandPortDisable, kPortIndexOutput),
6147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
6148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6149349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                mCodec->freeOutputBuffersNotOwnedByComponent();
6150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
615231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            } else if (data2 == OMX_IndexConfigCommonOutputCrop) {
615331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
6154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
6155ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08x",
6156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->mComponentName.c_str(), data2);
6157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
6158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventBufferFlag:
6163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
6169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
6173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6174f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
6175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ACodec *codec)
6176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
6177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6179f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
6180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
6181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput) {
6182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return FREE_BUFFERS;
6183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
6186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
6188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6190f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onMessageReceived(
6191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
6192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
6193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
6195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
6196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
6197349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case kWhatResume:
6198e6eea3a6b6e0cf92287ec1ceb8350f201d17e1acPer Persson        case kWhatSetParameters:
6199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6200349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            if (msg->what() == kWhatResume) {
62013856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
6202349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            }
6203349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
6205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
6211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
6215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6217f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::OutputPortSettingsChangedState::stateEntered() {
62183856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now handling output port settings change",
6219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mCodec->mComponentName.c_str());
6220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6222f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onOMXEvent(
6223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
6225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
6226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
62280806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (data2 != (OMX_U32)kPortIndexOutput) {
62290806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGW("ignoring EventCmdComplete CommandPortDisable for port %u", data2);
62300806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    return false;
62310806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
6232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
62330806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGV("[%s] Output port now disabled.", mCodec->mComponentName.c_str());
6234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
62350806340688c937e7b78c2d89db3809274130df4eLajos Molnar                status_t err = OK;
62360806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (!mCodec->mBuffers[kPortIndexOutput].isEmpty()) {
62370806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGE("disabled port should be empty, but has %zu buffers",
62380806340688c937e7b78c2d89db3809274130df4eLajos Molnar                            mCodec->mBuffers[kPortIndexOutput].size());
62390806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    err = FAILED_TRANSACTION;
62400806340688c937e7b78c2d89db3809274130df4eLajos Molnar                } else {
62410806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->mDealer[kPortIndexOutput].clear();
62420806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
6243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
62440806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err == OK) {
62450806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    err = mCodec->mOMX->sendCommand(
62460806340688c937e7b78c2d89db3809274130df4eLajos Molnar                            mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput);
62470806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
6248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
62490806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err == OK) {
62500806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    err = mCodec->allocateBuffersOnPort(kPortIndexOutput);
62510806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGE_IF(err != OK, "Failed to allocate output port buffers after port "
62520806340688c937e7b78c2d89db3809274130df4eLajos Molnar                            "reconfiguration: (%d)", err);
62530806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
6254cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
62550806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err != OK) {
6256251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
6257d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
6258755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // This is technically not correct, but appears to be
6259755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the only way to free the component instance.
6260755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // Controlled transitioning from excecuting->idle
6261755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // and idle->loaded seem impossible probably because
6262755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the output port never finishes re-enabling.
6263755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mShutdownInProgress = true;
6264755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mKeepComponentAllocated = false;
6265755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->changeState(mCodec->mLoadedState);
6266cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                }
6267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
6269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
6270777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (data2 != (OMX_U32)kPortIndexOutput) {
6271777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGW("ignoring EventCmdComplete OMX_CommandPortEnable for port %u", data2);
6272777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return false;
6273777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
6274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
627531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
627631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
62770806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGV("[%s] Output port now reenabled.", mCodec->mComponentName.c_str());
6278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6279349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                if (mCodec->mExecutingState->active()) {
6280349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    mCodec->mExecutingState->submitOutputBuffers();
6281349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                }
6282349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mExecutingState);
6284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
6286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
6287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
6289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
6293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
6297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6298f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
62995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : BaseState(codec),
63005778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mComponentNowIdle(false) {
6301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6303f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
6304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
6305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
6307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
6308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
6310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
63110806340688c937e7b78c2d89db3809274130df4eLajos Molnar            ALOGW("Ignoring flush request in ExecutingToIdleState");
6312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
6316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
6318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
6325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
6329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6331f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::stateEntered() {
63323856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
633331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
63345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mComponentNowIdle = false;
633531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mCodec->mSentFormat = false;
6336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6338f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onOMXEvent(
6339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
6341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
6342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
63430806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandStateSet
63440806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    || data2 != (OMX_U32)OMX_StateIdle) {
63450806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("Unexpected command completion in ExecutingToIdleState: %s(%u) %s(%u)",
63460806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1,
63470806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_STATETYPE)data2), data2);
63480806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
63490806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
63500806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
63525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mComponentNowIdle = true;
63535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            changeStateIfWeOwnAllBuffers();
6355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6359349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
6360349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventBufferFlag:
6361349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
6362349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We're shutting down and don't care about this anymore.
6363349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
6364349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
6365349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
6368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
63700af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
6371f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
63725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
63730806340688c937e7b78c2d89db3809274130df4eLajos Molnar        status_t err = mCodec->mOMX->sendCommand(
63740806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded);
63750806340688c937e7b78c2d89db3809274130df4eLajos Molnar        if (err == OK) {
63760806340688c937e7b78c2d89db3809274130df4eLajos Molnar            err = mCodec->freeBuffersOnPort(kPortIndexInput);
63770806340688c937e7b78c2d89db3809274130df4eLajos Molnar            status_t err2 = mCodec->freeBuffersOnPort(kPortIndexOutput);
63780806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err == OK) {
63790806340688c937e7b78c2d89db3809274130df4eLajos Molnar                err = err2;
63800806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
63810806340688c937e7b78c2d89db3809274130df4eLajos Molnar        }
6382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
63830167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown)
63840167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && mCodec->mNativeWindow != NULL) {
6385bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // We push enough 1x1 blank buffers to ensure that one of
6386bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // them has made it to the display.  This allows the OMX
6387bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // component teardown to zero out any protected buffers
6388bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // without the risk of scanning out one of those buffers.
6389b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar            pushBlankBuffersToNativeWindow(mCodec->mNativeWindow.get());
6390bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
6391bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
63920806340688c937e7b78c2d89db3809274130df4eLajos Molnar        if (err != OK) {
63930806340688c937e7b78c2d89db3809274130df4eLajos Molnar            mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
63940806340688c937e7b78c2d89db3809274130df4eLajos Molnar            return;
63950806340688c937e7b78c2d89db3809274130df4eLajos Molnar        }
63960806340688c937e7b78c2d89db3809274130df4eLajos Molnar
6397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mIdleToLoadedState);
6398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6401f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onInputBufferFilled(
6402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
6403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
6404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
6406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6408f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onOutputBufferDrained(
6409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
6410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
6411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
6413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
6416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6417f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
6418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
6419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6421f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
6422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
6423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
6425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
6426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
6428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
6434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
6436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
64370806340688c937e7b78c2d89db3809274130df4eLajos Molnar            ALOGE("Got flush request in IdleToLoadedState");
6438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
6443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
6447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6449f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToLoadedState::stateEntered() {
64503856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
6451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6453f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onOMXEvent(
6454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
6456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
6457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
64580806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandStateSet
64590806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    || data2 != (OMX_U32)OMX_StateLoaded) {
64600806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("Unexpected command completion in IdleToLoadedState: %s(%u) %s(%u)",
64610806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1,
64620806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_STATETYPE)data2), data2);
64630806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
64640806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
64650806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6467c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->changeState(mCodec->mLoadedState);
6468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
6474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
6478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6479f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::FlushingState::FlushingState(ACodec *codec)
6480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
6481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6483f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::stateEntered() {
64843856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
6485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
6487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6489f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
6490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
6491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
6493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
6494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
6496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
6500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing this right now.
6502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
6508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
6512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6514f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onOMXEvent(
6515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6516ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGV("[%s] FlushingState onOMXEvent(%u,%d)",
6517ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar            mCodec->mComponentName.c_str(), event, (OMX_S32)data1);
6518d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
6519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
6520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
6521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
65220806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandFlush) {
65230806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("unexpected EventCmdComplete %s(%d) data2:%d in FlushingState",
65240806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1, data2);
65250806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
65260806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
65270806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
6530777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (mFlushComplete[data2]) {
6531777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGW("Flush already completed for %s port",
6532777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            data2 == kPortIndexInput ? "input" : "output");
6533777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return true;
6534777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
6535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mFlushComplete[data2] = true;
6536e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber
65370806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (mFlushComplete[kPortIndexInput] && mFlushComplete[kPortIndexOutput]) {
6538e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                    changeStateIfWeOwnAllBuffers();
6539e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                }
6540777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            } else if (data2 == OMX_ALL) {
6541777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (!mFlushComplete[kPortIndexInput] || !mFlushComplete[kPortIndexOutput]) {
6542777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGW("received flush complete event for OMX_ALL before ports have been"
6543777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            "flushed (%d/%d)",
6544777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mFlushComplete[kPortIndexInput], mFlushComplete[kPortIndexOutput]);
6545777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return false;
6546777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
6547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                changeStateIfWeOwnAllBuffers();
6549777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            } else {
6550777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                ALOGW("data2 not OMX_ALL but %u in EventCmdComplete CommandFlush", data2);
6551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
6552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6556349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
6557349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
65581d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec);
6559349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("type", omx_message::EVENT);
6560609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            msg->setInt32("node", mCodec->mNode);
6561349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("event", event);
6562349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data1", data1);
6563349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data2", data2);
6564349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
65653856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
6566349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                 mCodec->mComponentName.c_str());
6567349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6568349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mCodec->deferMessage(msg);
6569349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6570349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
6571349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
6572349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
6575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
6578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6580f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
6581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
6582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
6584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6586f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
6587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
6588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
6590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6592f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
6593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mFlushComplete[kPortIndexInput]
6594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mFlushComplete[kPortIndexOutput]
6595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mCodec->allYourBuffersAreBelongToUs()) {
65967e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // We now own all buffers except possibly those still queued with
65977e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // the native window for rendering. Let's get those back as well.
65987e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
65997e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
6600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
6601d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatFlushCompleted);
6602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->post();
6603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->mPortEOS[kPortIndexInput] =
6605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mPortEOS[kPortIndexOutput] = false;
6606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6607dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber        mCodec->mInputEOSResult = OK;
6608dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
6609f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        if (mCodec->mSkipCutBuffer != NULL) {
6610f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen            mCodec->mSkipCutBuffer->clear();
6611f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        }
6612f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen
6613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mExecutingState);
6614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
6618