ACodec.cpp revision 0806340688c937e7b78c2d89db3809274130df4e
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);
135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::FILL_BUFFER_DONE:
139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
140609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                msg->setInt32(
141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "buffer", omx_msg.u.extended_buffer_data.buffer);
142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "range_offset",
144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.range_offset);
145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "range_length",
147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.range_length);
148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "flags",
150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.flags);
151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt64(
152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "timestamp",
153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.timestamp);
154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            default:
158777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                ALOGE("Unrecognized message type: %d", omx_msg.type);
159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->post();
163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
165f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual ~CodecObserver() {}
167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
168f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> mNotify;
170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(CodecObserver);
172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
176f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::BaseState : public AState {
177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState(ACodec *codec, const sp<AState> &parentState = NULL);
178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
179f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    enum PortMode {
181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        KEEP_BUFFERS,
182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        RESUBMIT_BUFFERS,
183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        FREE_BUFFERS,
184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ACodec *mCodec;
187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void postFillThisBuffer(BufferInfo *info);
198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
199f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXMessage(const sp<AMessage> &msg);
201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXEmptyBufferDone(IOMX::buffer_id bufferID);
203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXFillBufferDone(
205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID,
206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            size_t rangeOffset, size_t rangeLength,
207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            OMX_U32 flags,
208784e24e386b088c05d653ab482f2e95cb53e3d01Andy Hung            int64_t timeUs);
209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void getMoreInputDataIfPossible();
211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(BaseState);
213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
217ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberstruct ACodec::DeathNotifier : public IBinder::DeathRecipient {
218ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    DeathNotifier(const sp<AMessage> &notify)
219ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        : mNotify(notify) {
220ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
221ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
222ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual void binderDied(const wp<IBinder> &) {
223ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mNotify->post();
224ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
225ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
226ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprotected:
227ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual ~DeathNotifier() {}
228ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
229ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprivate:
230ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> mNotify;
231ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
232ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(DeathNotifier);
233ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber};
234ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
235f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::UninitializedState : public ACodec::BaseState {
236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    UninitializedState(ACodec *codec);
237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
238f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
240c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
242f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void onSetup(const sp<AMessage> &msg);
244c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onAllocateComponent(const sp<AMessage> &msg);
245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
246ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<DeathNotifier> mDeathNotifier;
247ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(UninitializedState);
249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
253c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberstruct ACodec::LoadedState : public ACodec::BaseState {
254c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    LoadedState(ACodec *codec);
255c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
256c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprotected:
257c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
258c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
259c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
260c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprivate:
261c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    friend struct ACodec::UninitializedState;
262c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
263c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onConfigureComponent(const sp<AMessage> &msg);
2647cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    void onCreateInputSurface(const sp<AMessage> &msg);
265d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    void onUsePersistentInputSurface(const sp<AMessage> &msg);
266c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onStart();
267c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onShutdown(bool keepComponentAllocated);
268c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
269d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    status_t setupInputSurface();
270d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
271c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedState);
272c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber};
273c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
274c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
275c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
276f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::LoadedToIdleState : public ACodec::BaseState {
277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    LoadedToIdleState(ACodec *codec);
278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
279f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
284f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t allocateBuffers();
286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedToIdleState);
288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
292f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToExecutingState : public ACodec::BaseState {
293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToExecutingState(ACodec *codec);
294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
295f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
300f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToExecutingState);
302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
306f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingState : public ACodec::BaseState {
307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingState(ACodec *codec);
308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
309054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitRegularOutputBuffers();
310054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitOutputMetaBuffers();
311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void submitOutputBuffers();
312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Submit output buffers to the decoder, submit input buffers to client
314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // to fill with data.
315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void resume();
316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
317349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    // Returns true iff input and output buffers are in play.
318349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool active() const { return mActive; }
319349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
320f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
327f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
328349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool mActive;
329349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingState);
331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
335f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::OutputPortSettingsChangedState : public ACodec::BaseState {
336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OutputPortSettingsChangedState(ACodec *codec);
337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
338f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
345f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(OutputPortSettingsChangedState);
347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
351f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingToIdleState : public ACodec::BaseState {
352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingToIdleState(ACodec *codec);
353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
354f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
363f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool mComponentNowIdle;
3675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingToIdleState);
369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
373f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToLoadedState : public ACodec::BaseState {
374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToLoadedState(ACodec *codec);
375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
376f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
382f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToLoadedState);
384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
388f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::FlushingState : public ACodec::BaseState {
389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    FlushingState(ACodec *codec);
390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
391f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
400f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool mFlushComplete[2];
402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(FlushingState);
406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
410f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ACodec()
411afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    : mQuirks(0),
412609b815a3131d22da38b2f452faa9f89daad4039Andy Hung      mNode(0),
4135778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mSentFormat(false),
4148db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu      mIsVideo(false),
415c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber      mIsEncoder(false),
416308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang      mUseMetadataOnEncoderOutput(false),
4179806555d3930be43e11106281dee354820ac1c88Andreas Huber      mShutdownInProgress(false),
41854b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar      mExplicitShutdown(false),
4199806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderDelay(0),
4209806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderPadding(0),
421e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang      mRotationDegrees(0),
4229806555d3930be43e11106281dee354820ac1c88Andreas Huber      mChannelMaskPresent(false),
423054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mChannelMask(0),
424054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mDequeueCounter(0),
425054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mStoreMetaDataInOutputBuffers(false),
426011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar      mLegacyAdaptiveExperiment(false),
427a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber      mMetaDataBuffersToSubmit(0),
42894ee4b708acfa941581160b267afb79192b1d816Chong Zhang      mRepeatFrameDelayUs(-1ll),
4292c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang      mMaxPtsGapUs(-1ll),
43037b2b389139ed638831e49708c947863eef631efRonghua Wu      mMaxFps(-1),
4312c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang      mTimePerFrameUs(-1ll),
432609b815a3131d22da38b2f452faa9f89daad4039Andy Hung      mTimePerCaptureUs(-1ll),
433ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad      mCreateInputBuffersSuspended(false),
434ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad      mTunneled(false) {
435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mUninitializedState = new UninitializedState(this);
436c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mLoadedState = new LoadedState(this);
437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mLoadedToIdleState = new LoadedToIdleState(this);
438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToExecutingState = new IdleToExecutingState(this);
439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingState = new ExecutingState(this);
440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOutputPortSettingsChangedState =
442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        new OutputPortSettingsChangedState(this);
443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingToIdleState = new ExecutingToIdleState(this);
445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToLoadedState = new IdleToLoadedState(this);
446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushingState = new FlushingState(this);
447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
449dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber    mInputEOSResult = OK;
450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeState(mUninitializedState);
452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
454f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::~ACodec() {
455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
457f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::setNotificationMessage(const sp<AMessage> &msg) {
458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mNotify = msg;
459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
461f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::initiateSetup(const sp<AMessage> &msg) {
462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setWhat(kWhatSetup);
4631d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    msg->setTarget(this);
464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
467a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Hubervoid ACodec::signalSetParameters(const sp<AMessage> &params) {
4681d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetParameters, this);
469a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->setMessage("params", params);
470a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->post();
471a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
472a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4735778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateAllocateComponent(const sp<AMessage> &msg) {
4745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatAllocateComponent);
4751d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    msg->setTarget(this);
4765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4775778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4795778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateConfigureComponent(const sp<AMessage> &msg) {
4805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatConfigureComponent);
4811d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    msg->setTarget(this);
4825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4835778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4851dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t ACodec::setSurface(const sp<Surface> &surface) {
4861dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetSurface, this);
4871dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    msg->setObject("surface", surface);
4881dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
4891dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    sp<AMessage> response;
4901dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    status_t err = msg->postAndAwaitResponse(&response);
4911dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
4921dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err == OK) {
4931dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        (void)response->findInt32("err", &err);
4941dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
4951dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    return err;
4961dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar}
4971dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
4987cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::initiateCreateInputSurface() {
4991d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatCreateInputSurface, this))->post();
5007cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
5017cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
502d291c222357303b9611cab89d0c3b047584ef377Chong Zhangvoid ACodec::initiateUsePersistentInputSurface(
503d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        const sp<PersistentSurface> &surface) {
504d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<AMessage> msg = new AMessage(kWhatUsePersistentInputSurface, this);
505d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    msg->setObject("input-surface", surface);
506d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    msg->post();
507d291c222357303b9611cab89d0c3b047584ef377Chong Zhang}
508d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5097cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::signalEndOfInputStream() {
5101d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatSignalEndOfInputStream, this))->post();
5117cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
5127cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
5135778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateStart() {
5141d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatStart, this))->post();
5155778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
5165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
517f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalFlush() {
5187a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] signalFlush", mComponentName.c_str());
5191d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatFlush, this))->post();
520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
522f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalResume() {
5231d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatResume, this))->post();
524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
526c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::initiateShutdown(bool keepComponentAllocated) {
5271d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatShutdown, this);
528c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->setInt32("keepComponentAllocated", keepComponentAllocated);
529c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->post();
53030358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar    if (!keepComponentAllocated) {
53130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        // ensure shutdown completes in 3 seconds
5321d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar        (new AMessage(kWhatReleaseCodecInstance, this))->post(3000000);
53330358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar    }
534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
536496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubervoid ACodec::signalRequestIDRFrame() {
5371d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatRequestIDRFrame, this))->post();
538496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
539496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5404dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
5414dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// Some codecs may return input buffers before having them processed.
5424dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// This causes a halt if we already signaled an EOS on the input
5434dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// port.  For now keep submitting an output buffer if there was an
5444dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// EOS on the input port, but not yet on the output port.
5454dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnarvoid ACodec::signalSubmitOutputMetaDataBufferIfEOS_workaround() {
5464dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    if (mPortEOS[kPortIndexInput] && !mPortEOS[kPortIndexOutput] &&
5474dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            mMetaDataBuffersToSubmit > 0) {
5481d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar        (new AMessage(kWhatSubmitOutputMetaDataBufferIfEOS, this))->post();
5494dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    }
5504dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar}
5514dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
5521dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t ACodec::handleSetSurface(const sp<Surface> &surface) {
5531dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // allow keeping unset surface
5541dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (surface == NULL) {
5551dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        if (mNativeWindow != NULL) {
5561dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            ALOGW("cannot unset a surface");
5571dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            return INVALID_OPERATION;
5581dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
5591dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return OK;
5601dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
5611dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
5621dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // allow keeping unset surface
5631dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mNativeWindow == NULL) {
5641dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGW("component was not configured with a surface");
5651dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return INVALID_OPERATION;
5661dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
5671dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
5681dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    ANativeWindow *nativeWindow = surface.get();
5691dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // if we have not yet started the codec, we can simply set the native window
5701dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mBuffers[kPortIndexInput].size() == 0) {
5711dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        mNativeWindow = surface;
5721dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return OK;
5731dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
5741dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
5751dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // we do not support changing a tunneled surface after start
5761dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mTunneled) {
5771dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGW("cannot change tunneled surface");
5781dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return INVALID_OPERATION;
5791dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
5801dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
5811dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    status_t err = setupNativeWindowSizeFormatAndUsage(nativeWindow);
5821dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != OK) {
5831dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
5841dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
5851dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
5861dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // get min undequeued count. We cannot switch to a surface that has a higher
5871dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // undequeued count than we allocated.
5881dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    int minUndequeuedBuffers = 0;
5891dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    err = nativeWindow->query(
5901dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            nativeWindow, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
5911dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            &minUndequeuedBuffers);
5921dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != 0) {
5931dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
5941dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                strerror(-err), -err);
5951dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
5961dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
5971dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (minUndequeuedBuffers > (int)mNumUndequeuedBuffers) {
5981dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGE("new surface holds onto more buffers (%d) than planned for (%zu)",
5991dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                minUndequeuedBuffers, mNumUndequeuedBuffers);
6001dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return BAD_VALUE;
6011dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6021dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
6031dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // we cannot change the number of output buffers while OMX is running
6041dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // set up surface to the same count
6051dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    Vector<BufferInfo> &buffers = mBuffers[kPortIndexOutput];
6061dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    ALOGV("setting up surface for %zu buffers", buffers.size());
6071dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
6081dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    err = native_window_set_buffer_count(nativeWindow, buffers.size());
6091dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != 0) {
6101dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
6111dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                -err);
6121dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
6131dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6141dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
615dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    // need to enable allocation when attaching
616dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    surface->getIGraphicBufferProducer()->allowAllocation(true);
617dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar
6181dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // for meta data mode, we move dequeud buffers to the new surface.
6191dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // for non-meta mode, we must move all registered buffers
6201dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    for (size_t i = 0; i < buffers.size(); ++i) {
6211dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        const BufferInfo &info = buffers[i];
6221dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        // skip undequeued buffers for meta data mode
6231dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        if (mStoreMetaDataInOutputBuffers
624011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                && !mLegacyAdaptiveExperiment
6251dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                && info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
6261dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            ALOGV("skipping buffer %p", info.mGraphicBuffer->getNativeBuffer());
6271dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            continue;
6281dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
6291dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGV("attaching buffer %p", info.mGraphicBuffer->getNativeBuffer());
6301dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
6311dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        err = surface->attachBuffer(info.mGraphicBuffer->getNativeBuffer());
6321dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        if (err != OK) {
6331dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            ALOGE("failed to attach buffer %p to the new surface: %s (%d)",
6341dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    info.mGraphicBuffer->getNativeBuffer(),
6351dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    strerror(-err), -err);
6361dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            return err;
6371dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
6381dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6391dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
6401dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // cancel undequeued buffers to new surface
641011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar    if (!mStoreMetaDataInOutputBuffers || mLegacyAdaptiveExperiment) {
6421dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        for (size_t i = 0; i < buffers.size(); ++i) {
6431dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            const BufferInfo &info = buffers[i];
6441dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
6451dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                ALOGV("canceling buffer %p", info.mGraphicBuffer->getNativeBuffer());
6461dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                err = nativeWindow->cancelBuffer(
6471dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                        nativeWindow, info.mGraphicBuffer->getNativeBuffer(), -1);
6481dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                if (err != OK) {
6491dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    ALOGE("failed to cancel buffer %p to the new surface: %s (%d)",
6501dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                            info.mGraphicBuffer->getNativeBuffer(),
6511dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                            strerror(-err), -err);
6521dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    return err;
6531dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                }
6541dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            }
6551dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
6561dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        // disallow further allocation
6571dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        (void)surface->getIGraphicBufferProducer()->allowAllocation(false);
6581dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6591dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
660484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar    // push blank buffers to previous window if requested
661484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar    if (mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown) {
662484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar        pushBlankBuffersToNativeWindow(mNativeWindow.get());
663484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar    }
664484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar
6651dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    mNativeWindow = nativeWindow;
6661dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    return OK;
6671dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar}
6681dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
669f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mDealer[portIndex] == NULL);
673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mBuffers[portIndex].isEmpty());
674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
677054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (mStoreMetaDataInOutputBuffers) {
678054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputMetaDataBuffers();
679054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
680054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputBuffersFromNativeWindow();
681054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
6825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
6835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
6845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
6855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = portIndex;
686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
6885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err == OK) {
691609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGV("[%s] Allocating %u buffers of size %u on %s port",
6925778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mComponentName.c_str(),
6935778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    def.nBufferCountActual, def.nBufferSize,
6945778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    portIndex == kPortIndexInput ? "input" : "output");
695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            size_t totalSize = def.nBufferCountActual * def.nBufferSize;
6975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
7005778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
701777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (mem.get() == NULL) {
702777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return NO_MEMORY;
703777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
705ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                BufferInfo info;
706ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                info.mStatus = BufferInfo::OWNED_BY_US;
707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
708afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                uint32_t requiresAllocateBufferBit =
709afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                    (portIndex == kPortIndexInput)
710afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        ? OMXCodec::kRequiresAllocateBufferOnInputPorts
711afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        : OMXCodec::kRequiresAllocateBufferOnOutputPorts;
7121065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
713308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                if ((portIndex == kPortIndexInput && (mFlags & kFlagIsSecure))
714308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        || mUseMetadataOnEncoderOutput) {
715ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    mem.clear();
716ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
717ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    void *ptr;
718ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->allocateBuffer(
719ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, def.nBufferSize, &info.mBufferID,
720ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            &ptr);
721ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
722308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    int32_t bufSize = mUseMetadataOnEncoderOutput ?
723308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                            (4 + sizeof(buffer_handle_t)) : def.nBufferSize;
724308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
725308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    info.mData = new ABuffer(ptr, bufSize);
726ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                } else if (mQuirks & requiresAllocateBufferBit) {
7275778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    err = mOMX->allocateBufferWithBackup(
728ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, mem, &info.mBufferID);
7295778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
730ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->useBuffer(mNode, portIndex, mem, &info.mBufferID);
731ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                }
732ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
733ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                if (mem != NULL) {
734ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    info.mData = new ABuffer(mem->pointer(), def.nBufferSize);
7355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
7361065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
7375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mBuffers[portIndex].push(info);
7381065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            }
7391065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
7405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
7435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
7445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> notify = mNotify->dup();
747d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatBuffersAllocated);
7485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("portIndex", portIndex);
750eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
751eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    sp<PortDescription> desc = new PortDescription;
752eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
7535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
754eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        const BufferInfo &info = mBuffers[portIndex][i];
7555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
756eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        desc->addBuffer(info.mBufferID, info.mData);
757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
759eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    notify->setObject("portDesc", desc);
7605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->post();
7615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7651dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t ACodec::setupNativeWindowSizeFormatAndUsage(ANativeWindow *nativeWindow /* nonnull */) {
7661dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    OMX_PARAM_PORTDEFINITIONTYPE def;
7671dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    InitOMXParams(&def);
7681dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    def.nPortIndex = kPortIndexOutput;
7691dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
7701dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    status_t err = mOMX->getParameter(
7711dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
7721dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
7731dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != OK) {
7741dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
7751dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7761dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
7771dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    OMX_U32 usage = 0;
7781dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
7791dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != 0) {
7801dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGW("querying usage flags from OMX IL component failed: %d", err);
7811dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        // XXX: Currently this error is logged, but not fatal.
7821dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        usage = 0;
7831dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7841dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    int omxUsage = usage;
7851dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
7861dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mFlags & kFlagIsGrallocUsageProtected) {
7871dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        usage |= GRALLOC_USAGE_PROTECTED;
7881dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7891dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
790b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar    usage |= GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP;
791b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar
7921dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    ALOGV("gralloc usage: %#x(OMX) => %#x(ACodec)", omxUsage, usage);
7931dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    return setNativeWindowSizeFormatAndUsage(
7941dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            nativeWindow,
7951dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            def.format.video.nFrameWidth,
7961dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            def.format.video.nFrameHeight,
7971dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            def.format.video.eColorFormat,
7981dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            mRotationDegrees,
7991dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            usage);
8001dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar}
8011dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
8021dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t ACodec::configureOutputBuffersFromNativeWindow(
8031dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        OMX_U32 *bufferCount, OMX_U32 *bufferSize,
8041dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        OMX_U32 *minUndequeuedBuffers) {
8051dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    OMX_PARAM_PORTDEFINITIONTYPE def;
8061dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    InitOMXParams(&def);
8071dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    def.nPortIndex = kPortIndexOutput;
8081dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
8091dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    status_t err = mOMX->getParameter(
8101dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
8111dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
8121dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err == OK) {
8131dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        err = setupNativeWindowSizeFormatAndUsage(mNativeWindow.get());
8141dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
8151dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != OK) {
8161dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
8171dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
8181dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
819ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // Exits here for tunneled video playback codecs -- i.e. skips native window
820ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // buffer allocation step as this is managed by the tunneled OMX omponent
821ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // itself and explicitly sets def.nBufferCountActual to 0.
822ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    if (mTunneled) {
823ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        ALOGV("Tunneled Playback: skipping native window buffer allocation.");
824ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        def.nBufferCountActual = 0;
825ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        err = mOMX->setParameter(
826ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
827ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
828ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *minUndequeuedBuffers = 0;
829ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *bufferCount = 0;
830ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *bufferSize = 0;
831ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        return err;
832ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    }
833ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
834054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *minUndequeuedBuffers = 0;
835258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    err = mNativeWindow->query(
836258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
837054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (int *)minUndequeuedBuffers);
838258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
839258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    if (err != 0) {
84029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
841258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                strerror(-err), -err);
842258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        return err;
843258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
844258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
845e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // FIXME: assume that surface is controlled by app (native window
846e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // returns the number for the case when surface is not controlled by app)
8471faa41704e0b976e546321effcb09a85767d51baLajos Molnar    // FIXME2: This means that minUndeqeueudBufs can be 1 larger than reported
8481faa41704e0b976e546321effcb09a85767d51baLajos Molnar    // For now, try to allocate 1 more buffer, but don't fail if unsuccessful
849e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar
850e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // Use conservative allocation while also trying to reduce starvation
851e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //
852e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // 1. allocate at least nBufferCountMin + minUndequeuedBuffers - that is the
853e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //    minimum needed for the consumer to be able to work
854e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // 2. try to allocate two (2) additional buffers to reduce starvation from
855e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //    the consumer
8561faa41704e0b976e546321effcb09a85767d51baLajos Molnar    //    plus an extra buffer to account for incorrect minUndequeuedBufs
8571faa41704e0b976e546321effcb09a85767d51baLajos Molnar    for (OMX_U32 extraBuffers = 2 + 1; /* condition inside loop */; extraBuffers--) {
858e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        OMX_U32 newBufferCount =
859e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            def.nBufferCountMin + *minUndequeuedBuffers + extraBuffers;
860258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        def.nBufferCountActual = newBufferCount;
861258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        err = mOMX->setParameter(
862258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
863258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
864e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        if (err == OK) {
865e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            *minUndequeuedBuffers += extraBuffers;
866e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            break;
867e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        }
868e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar
869609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGW("[%s] setting nBufferCountActual to %u failed: %d",
870e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar                mComponentName.c_str(), newBufferCount, err);
871e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        /* exit condition */
872e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        if (extraBuffers == 0) {
873258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            return err;
874258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        }
875258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
876258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffer_count(
878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(), def.nBufferCountActual);
879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
88129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                -err);
883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
886054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferCount = def.nBufferCountActual;
887054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferSize =  def.nBufferSize;
888054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
889054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
890054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
891054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputBuffersFromNativeWindow() {
892054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
893054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
894054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
895054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
896054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
897e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    mNumUndequeuedBuffers = minUndequeuedBuffers;
898054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
8993298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia    if (!mStoreMetaDataInOutputBuffers) {
9003298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia        static_cast<Surface*>(mNativeWindow.get())
9013298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia                ->getIGraphicBufferProducer()->allowAllocation(true);
9023298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia    }
9033298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia
904609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Allocating %u buffers from a native window of size %u on "
905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         "output port",
906054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount, bufferSize);
907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Dequeue buffers and send them to OMX
909054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
9108ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev        ANativeWindowBuffer *buf;
9111e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
91329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
91874006804065941841883c4b46ee785070164023fJamie Gennis        BufferInfo info;
91974006804065941841883c4b46ee785070164023fJamie Gennis        info.mStatus = BufferInfo::OWNED_BY_US;
920054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(NULL /* data */, bufferSize /* capacity */);
92174006804065941841883c4b46ee785070164023fJamie Gennis        info.mGraphicBuffer = graphicBuffer;
92274006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].push(info);
92374006804065941841883c4b46ee785070164023fJamie Gennis
924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferId;
925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &bufferId);
927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
928609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGE("registering GraphicBuffer %u with OMX IL component failed: "
92974006804065941841883c4b46ee785070164023fJamie Gennis                 "%d", i, err);
930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
93374006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
93474006804065941841883c4b46ee785070164023fJamie Gennis
935609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGV("[%s] Registered graphic buffer with ID %u (pointer = %p)",
936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mComponentName.c_str(),
937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             bufferId, graphicBuffer.get());
938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelStart;
941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelEnd;
942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // If an error occurred while dequeuing we need to cancel any buffers
945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // that were dequeued.
946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelStart = 0;
94774006804065941841883c4b46ee785070164023fJamie Gennis        cancelEnd = mBuffers[kPortIndexOutput].size();
948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
949054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // Return the required minimum undequeued buffers to the native window.
950054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelStart = bufferCount - minUndequeuedBuffers;
951054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelEnd = bufferCount;
952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
9563fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        status_t error = cancelBufferToNativeWindow(info);
9573fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        if (err == 0) {
9583fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia            err = error;
9593fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        }
960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9623298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia    if (!mStoreMetaDataInOutputBuffers) {
9633298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia        static_cast<Surface*>(mNativeWindow.get())
9643298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia                ->getIGraphicBufferProducer()->allowAllocation(false);
9653298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia    }
9663298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia
967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
970054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputMetaDataBuffers() {
971054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
972054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
973054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
974054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
975054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
976e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    mNumUndequeuedBuffers = minUndequeuedBuffers;
977054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
978e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar    ALOGV("[%s] Allocating %u meta buffers on output port",
979e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar         mComponentName.c_str(), bufferCount);
980e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
981e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar    size_t totalSize = bufferCount * 8;
982e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar    mDealer[kPortIndexOutput] = new MemoryDealer(totalSize, "ACodec");
983e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
984e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar    // Dequeue buffers and send them to OMX
985e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
986e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        BufferInfo info;
987e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        info.mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
988e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        info.mGraphicBuffer = NULL;
989e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        info.mDequeuedAt = mDequeueCounter;
990e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
991e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        sp<IMemory> mem = mDealer[kPortIndexOutput]->allocate(
992e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar                sizeof(struct VideoDecoderOutputMetaData));
993777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        if (mem.get() == NULL) {
994777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return NO_MEMORY;
995777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        }
996e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        info.mData = new ABuffer(mem->pointer(), mem->size());
997e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
998e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        // we use useBuffer for metadata regardless of quirks
999e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        err = mOMX->useBuffer(
1000e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar                mNode, kPortIndexOutput, mem, &info.mBufferID);
1001e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1002e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        mBuffers[kPortIndexOutput].push(info);
1003e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1004e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        ALOGV("[%s] allocated meta buffer with ID %u (pointer = %p)",
1005e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar             mComponentName.c_str(), info.mBufferID, mem->pointer());
1006e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar    }
1007e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1008011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar    if (mLegacyAdaptiveExperiment) {
1009e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        // preallocate and preregister buffers
1010011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        static_cast<Surface *>(mNativeWindow.get())
1011011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                ->getIGraphicBufferProducer()->allowAllocation(true);
1012011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
1013011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        ALOGV("[%s] Allocating %u buffers from a native window of size %u on "
1014011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar             "output port",
1015011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar             mComponentName.c_str(), bufferCount, bufferSize);
1016011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
1017011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        // Dequeue buffers then cancel them all
1018011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        for (OMX_U32 i = 0; i < bufferCount; i++) {
1019e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar            BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
1020e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1021011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            ANativeWindowBuffer *buf;
1022011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
1023011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            if (err != 0) {
1024011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
1025011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                break;
1026011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            }
1027011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
1028011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
1029e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar            mOMX->updateGraphicBufferInMeta(
1030e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar                    mNode, kPortIndexOutput, graphicBuffer, info->mBufferID);
1031e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar            info->mStatus = BufferInfo::OWNED_BY_US;
1032e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar            info->mGraphicBuffer = graphicBuffer;
1033011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        }
1034011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
1035011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        for (OMX_U32 i = 0; i < mBuffers[kPortIndexOutput].size(); i++) {
1036011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
1037011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            status_t error = cancelBufferToNativeWindow(info);
1038011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            if (err == OK) {
1039011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                err = error;
1040011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            }
1041011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        }
1042011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
1043011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        static_cast<Surface*>(mNativeWindow.get())
1044011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                ->getIGraphicBufferProducer()->allowAllocation(false);
1045011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar    }
1046011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
1047054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mMetaDataBuffersToSubmit = bufferCount - minUndequeuedBuffers;
1048054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
1049054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
1050054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1051054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::submitOutputMetaDataBuffer() {
1052054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mStoreMetaDataInOutputBuffers);
1053054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mMetaDataBuffersToSubmit == 0)
1054054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return OK;
1055054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1056054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *info = dequeueBufferFromNativeWindow();
10570806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (info == NULL) {
1058054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return ERROR_IO;
10590806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
1060054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1061609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] submitting output meta buffer ID %u for graphic buffer %p",
1062054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          mComponentName.c_str(), info->mBufferID, info->mGraphicBuffer.get());
1063054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1064054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    --mMetaDataBuffersToSubmit;
1065777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    status_t err = mOMX->fillBuffer(mNode, info->mBufferID);
1066777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (err == OK) {
1067777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
1068777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
1069054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1070777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    return err;
1071054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
1072054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
10730806340688c937e7b78c2d89db3809274130df4eLajos Molnar// static
10740806340688c937e7b78c2d89db3809274130df4eLajos Molnarconst char *ACodec::_asString(BufferInfo::Status s) {
10750806340688c937e7b78c2d89db3809274130df4eLajos Molnar    switch (s) {
10760806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_US:            return "OUR";
10770806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_COMPONENT:     return "COMPONENT";
10780806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_UPSTREAM:      return "UPSTREAM";
10790806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_DOWNSTREAM:    return "DOWNSTREAM";
10800806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_NATIVE_WINDOW: return "SURFACE";
10810806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::UNRECOGNIZED:           return "UNRECOGNIZED";
10820806340688c937e7b78c2d89db3809274130df4eLajos Molnar        default:                                 return "?";
10830806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
10840806340688c937e7b78c2d89db3809274130df4eLajos Molnar}
10850806340688c937e7b78c2d89db3809274130df4eLajos Molnar
10860806340688c937e7b78c2d89db3809274130df4eLajos Molnarvoid ACodec::dumpBuffers(OMX_U32 portIndex) {
10870806340688c937e7b78c2d89db3809274130df4eLajos Molnar    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
10880806340688c937e7b78c2d89db3809274130df4eLajos Molnar    ALOGI("[%s] %s port has %zu buffers:", mComponentName.c_str(),
10890806340688c937e7b78c2d89db3809274130df4eLajos Molnar            portIndex == kPortIndexInput ? "input" : "output", mBuffers[portIndex].size());
10900806340688c937e7b78c2d89db3809274130df4eLajos Molnar    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
10910806340688c937e7b78c2d89db3809274130df4eLajos Molnar        const BufferInfo &info = mBuffers[portIndex][i];
10920806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGI("  slot %2zu: #%8u %p/%p %s(%d) dequeued:%u",
10930806340688c937e7b78c2d89db3809274130df4eLajos Molnar                i, info.mBufferID, info.mGraphicBuffer.get(),
10940806340688c937e7b78c2d89db3809274130df4eLajos Molnar                info.mGraphicBuffer == NULL ? NULL : info.mGraphicBuffer->getNativeBuffer(),
10950806340688c937e7b78c2d89db3809274130df4eLajos Molnar                _asString(info.mStatus), info.mStatus, info.mDequeuedAt);
10960806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
10970806340688c937e7b78c2d89db3809274130df4eLajos Molnar}
10980806340688c937e7b78c2d89db3809274130df4eLajos Molnar
1099f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
1100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
1101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1102609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Calling cancelBuffer on buffer %u",
1103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mComponentName.c_str(), info->mBufferID);
1104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int err = mNativeWindow->cancelBuffer(
11061e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        mNativeWindow.get(), info->mGraphicBuffer.get(), -1);
1107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
11083fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia    ALOGW_IF(err != 0, "[%s] can not return buffer %u to native window",
11093fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia            mComponentName.c_str(), info->mBufferID);
11100806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // change ownership even if cancelBuffer fails
1111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
1112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
11133fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia    return err;
1114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1116f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
11178ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev    ANativeWindowBuffer *buf;
1118054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mNativeWindow.get() != NULL);
1119ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
1120ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    if (mTunneled) {
1121ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        ALOGW("dequeueBufferFromNativeWindow() should not be called in tunnel"
1122ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad              " video playback mode mode!");
1123ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        return NULL;
1124ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    }
1125ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
1126dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    do {
1127dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        if (native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf) != 0) {
1128dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            ALOGE("dequeueBuffer failed.");
1129dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            return NULL;
1130dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        }
1131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1132dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        bool stale = false;
1133dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
1134dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
1135dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar
1136dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            if (info->mGraphicBuffer != NULL &&
1137dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                info->mGraphicBuffer->handle == buf->handle) {
1138dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // Since consumers can attach buffers to BufferQueues, it is possible
1139dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // that a known yet stale buffer can return from a surface that we
1140dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // once used.  We can simply ignore this as we have already dequeued
1141dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // this buffer properly.  NOTE: this does not eliminate all cases,
1142dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // e.g. it is possible that we have queued the valid buffer to the
1143dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // NW, and a stale copy of the same buffer gets dequeued - which will
1144dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // be treated as the valid buffer by ACodec.
1145dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                if (info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
1146dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                    ALOGI("dequeued stale buffer %p. discarding", buf);
1147dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                    stale = true;
1148dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                    break;
1149dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                }
1150dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                ALOGV("dequeued buffer %p", info->mGraphicBuffer->getNativeBuffer());
1151dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                info->mStatus = BufferInfo::OWNED_BY_US;
1152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1153dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                return info;
1154dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            }
1155dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        }
1156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1157dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // It is also possible to receive a previously unregistered buffer
1158dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // in non-meta mode. These should be treated as stale buffers. The
1159dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // same is possible in meta mode, in which case, it will be treated
1160dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // as a normal buffer, which is not desirable.
1161dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // TODO: fix this.
1162011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        if (!stale && (!mStoreMetaDataInOutputBuffers || mLegacyAdaptiveExperiment)) {
1163dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            ALOGI("dequeued unrecognized (stale) buffer %p. discarding", buf);
1164dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            stale = true;
1165dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        }
1166dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        if (stale) {
1167dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            // TODO: detach stale buffer, but there is no API yet to do it.
1168dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            buf = NULL;
1169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1170dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    } while (buf == NULL);
1171054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1172dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    // get oldest undequeued buffer
1173dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    BufferInfo *oldest = NULL;
1174dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
1175dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        BufferInfo *info =
1176dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            &mBuffers[kPortIndexOutput].editItemAt(i);
1177054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW &&
1178054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (oldest == NULL ||
1179054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             // avoid potential issues from counter rolling over
1180054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mDequeueCounter - info->mDequeuedAt >
1181054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    mDequeueCounter - oldest->mDequeuedAt)) {
1182054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            oldest = info;
1183054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
1184054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1185054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
11860806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // it is impossible dequeue a buffer when there are no buffers with ANW
11870806340688c937e7b78c2d89db3809274130df4eLajos Molnar    CHECK(oldest != NULL);
11880806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // it is impossible to dequeue an unknown buffer in non-meta mode, as the
11890806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // while loop above does not complete
11900806340688c937e7b78c2d89db3809274130df4eLajos Molnar    CHECK(mStoreMetaDataInOutputBuffers);
1191054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
11920806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // discard buffer in LRU info and replace with new buffer
11930806340688c937e7b78c2d89db3809274130df4eLajos Molnar    oldest->mGraphicBuffer = new GraphicBuffer(buf, false);
11940806340688c937e7b78c2d89db3809274130df4eLajos Molnar    oldest->mStatus = BufferInfo::OWNED_BY_US;
1195d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar
11960806340688c937e7b78c2d89db3809274130df4eLajos Molnar    mOMX->updateGraphicBufferInMeta(
11970806340688c937e7b78c2d89db3809274130df4eLajos Molnar            mNode, kPortIndexOutput, oldest->mGraphicBuffer,
11980806340688c937e7b78c2d89db3809274130df4eLajos Molnar            oldest->mBufferID);
1199054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
12000806340688c937e7b78c2d89db3809274130df4eLajos Molnar    VideoDecoderOutputMetaData *metaData =
12010806340688c937e7b78c2d89db3809274130df4eLajos Molnar        reinterpret_cast<VideoDecoderOutputMetaData *>(
12020806340688c937e7b78c2d89db3809274130df4eLajos Molnar                oldest->mData->base());
12030806340688c937e7b78c2d89db3809274130df4eLajos Molnar    CHECK_EQ(metaData->eType, kMetadataBufferTypeGrallocSource);
1204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
12050806340688c937e7b78c2d89db3809274130df4eLajos Molnar    ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
12060806340688c937e7b78c2d89db3809274130df4eLajos Molnar            (unsigned)(oldest - &mBuffers[kPortIndexOutput][0]),
12070806340688c937e7b78c2d89db3809274130df4eLajos Molnar            mDequeueCounter - oldest->mDequeuedAt,
12080806340688c937e7b78c2d89db3809274130df4eLajos Molnar            metaData->pHandle,
12090806340688c937e7b78c2d89db3809274130df4eLajos Molnar            oldest->mGraphicBuffer->handle, oldest->mData->base());
1210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
12110806340688c937e7b78c2d89db3809274130df4eLajos Molnar    return oldest;
1212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1214f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
1215777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    status_t err = OK;
1216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[portIndex].size(); i-- > 0;) {
1217777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        status_t err2 = freeBuffer(portIndex, i);
1218777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        if (err == OK) {
1219777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            err = err2;
1220777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        }
1221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
12230806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // clear mDealer even on an error
1224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDealer[portIndex].clear();
1225777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    return err;
1226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1228349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huberstatus_t ACodec::freeOutputBuffersNotOwnedByComponent() {
1229777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    status_t err = OK;
1230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
1231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
1232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
1233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
12342ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // At this time some buffers may still be with the component
12352ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // or being drained.
12362ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT &&
12372ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar            info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) {
1238777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            status_t err2 = freeBuffer(kPortIndexOutput, i);
1239777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            if (err == OK) {
1240777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                err = err2;
1241777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            }
1242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1245777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    return err;
1246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1248f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
1249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
12500806340688c937e7b78c2d89db3809274130df4eLajos Molnar    status_t err = OK;
1251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
12520806340688c937e7b78c2d89db3809274130df4eLajos Molnar    switch (info->mStatus) {
12530806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_US:
12540806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (portIndex == kPortIndexOutput && mNativeWindow != NULL) {
12550806340688c937e7b78c2d89db3809274130df4eLajos Molnar                (void)cancelBufferToNativeWindow(info);
12560806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
12570806340688c937e7b78c2d89db3809274130df4eLajos Molnar            // fall through
1258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
12590806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_NATIVE_WINDOW:
12600806340688c937e7b78c2d89db3809274130df4eLajos Molnar            err = mOMX->freeBuffer(mNode, portIndex, info->mBufferID);
12610806340688c937e7b78c2d89db3809274130df4eLajos Molnar            break;
12620806340688c937e7b78c2d89db3809274130df4eLajos Molnar
12630806340688c937e7b78c2d89db3809274130df4eLajos Molnar        default:
12640806340688c937e7b78c2d89db3809274130df4eLajos Molnar            ALOGE("trying to free buffer not owned by us or ANW (%d)", info->mStatus);
12650806340688c937e7b78c2d89db3809274130df4eLajos Molnar            err = FAILED_TRANSACTION;
12660806340688c937e7b78c2d89db3809274130df4eLajos Molnar            break;
1267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1269777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    // remove buffer even if mOMX->freeBuffer fails
1270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mBuffers[portIndex].removeAt(i);
1271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1272777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    return err;
1273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1275f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::findBufferByID(
12760806340688c937e7b78c2d89db3809274130df4eLajos Molnar        uint32_t portIndex, IOMX::buffer_id bufferID, ssize_t *index) {
1277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
1278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
1279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mBufferID == bufferID) {
1281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (index != NULL) {
1282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                *index = i;
1283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
1285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1288777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    ALOGE("Could not find buffer with ID %u", bufferID);
1289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
1290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
12925778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setComponentRole(
1293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        bool isEncoder, const char *mime) {
1294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    struct MimeToRole {
1295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime;
1296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *decoderRole;
1297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *encoderRole;
1298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
1299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const MimeToRole kMimeToRole[] = {
1301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG,
1302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.mp3", "audio_encoder.mp3" },
13032944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
13042944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp1", "audio_encoder.mp1" },
13052944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
13062944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp2", "audio_encoder.mp2" },
1307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_NB,
1308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrnb", "audio_encoder.amrnb" },
1309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_WB,
1310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrwb", "audio_encoder.amrwb" },
1311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AAC,
1312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.aac", "audio_encoder.aac" },
1313729de186450f78c099637e1fce743fe531862c52Andreas Huber        { MEDIA_MIMETYPE_AUDIO_VORBIS,
1314729de186450f78c099637e1fce743fe531862c52Andreas Huber            "audio_decoder.vorbis", "audio_encoder.vorbis" },
1315bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian        { MEDIA_MIMETYPE_AUDIO_OPUS,
1316bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian            "audio_decoder.opus", "audio_encoder.opus" },
1317c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_MLAW,
1318c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" },
1319c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_ALAW,
1320c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711alaw", "audio_encoder.g711alaw" },
1321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_AVC,
1322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.avc", "video_encoder.avc" },
13232472b1c0d63454e5d90a982bd6c555de6c3127bdRachad        { MEDIA_MIMETYPE_VIDEO_HEVC,
13242472b1c0d63454e5d90a982bd6c555de6c3127bdRachad            "video_decoder.hevc", "video_encoder.hevc" },
1325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_MPEG4,
1326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.mpeg4", "video_encoder.mpeg4" },
1327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_H263,
1328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.h263", "video_encoder.h263" },
132994705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP8,
133094705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp8", "video_encoder.vp8" },
133194705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP9,
133294705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp9", "video_encoder.vp9" },
1333ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        { MEDIA_MIMETYPE_AUDIO_RAW,
1334ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            "audio_decoder.raw", "audio_encoder.raw" },
13352f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        { MEDIA_MIMETYPE_AUDIO_FLAC,
13362f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            "audio_decoder.flac", "audio_encoder.flac" },
1337ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        { MEDIA_MIMETYPE_AUDIO_MSGSM,
1338ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen            "audio_decoder.gsm", "audio_encoder.gsm" },
1339774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu        { MEDIA_MIMETYPE_VIDEO_MPEG2,
1340774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu            "video_decoder.mpeg2", "video_encoder.mpeg2" },
134197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        { MEDIA_MIMETYPE_AUDIO_AC3,
134297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            "audio_decoder.ac3", "audio_encoder.ac3" },
13438a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        { MEDIA_MIMETYPE_AUDIO_EAC3,
13448a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            "audio_decoder.eac3", "audio_encoder.eac3" },
1345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
1346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const size_t kNumMimeToRole =
1348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
1349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    size_t i;
1351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (i = 0; i < kNumMimeToRole; ++i) {
1352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcasecmp(mime, kMimeToRole[i].mime)) {
1353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (i == kNumMimeToRole) {
13585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_UNSUPPORTED;
1359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    const char *role =
1362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        isEncoder ? kMimeToRole[i].encoderRole
1363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                  : kMimeToRole[i].decoderRole;
1364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (role != NULL) {
1366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_PARAM_COMPONENTROLETYPE roleParams;
1367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        InitOMXParams(&roleParams);
1368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        strncpy((char *)roleParams.cRole,
1370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                role, OMX_MAX_STRINGNAME_SIZE - 1);
1371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
1373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->setParameter(
1375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamStandardComponentRole,
1376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &roleParams, sizeof(roleParams));
1377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
13795ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("[%s] Failed to set standard component role '%s'.",
1380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 mComponentName.c_str(), role);
13815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
1383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
13855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
1387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
13895778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::configureCodec(
1390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime, const sp<AMessage> &msg) {
13915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t encoder;
13925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("encoder", &encoder)) {
13935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        encoder = false;
13945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1396e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    sp<AMessage> inputFormat = new AMessage();
13974e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    sp<AMessage> outputFormat = mNotify->dup(); // will use this for kWhatOutputFormatChanged
1398e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
13995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mIsEncoder = encoder;
1400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14018db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu
14025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setComponentRole(encoder /* isEncoder */, mime);
14035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
14055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
14065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitRate = 0;
14092f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    // FLAC encoder doesn't need a bitrate, other encoders do
14102f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
14112f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            && !msg->findInt32("bitrate", &bitRate)) {
14125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
14135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1415d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    int32_t storeMeta;
1416d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (encoder
1417d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && msg->findInt32("store-metadata-in-buffers", &storeMeta)
1418d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && storeMeta != 0) {
1419d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE);
1420d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1421d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (err != OK) {
1422308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              ALOGE("[%s] storeMetaDataInBuffers (input) failed w/ err %d",
1423308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    mComponentName.c_str(), err);
1424d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1425308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              return err;
1426308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang          }
1427308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang      }
1428d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1429308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t prependSPSPPS = 0;
14303a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    if (encoder
14313a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
14323a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && prependSPSPPS != 0) {
14333a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        OMX_INDEXTYPE index;
14343a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        err = mOMX->getExtensionIndex(
14353a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                mNode,
14363a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                "OMX.google.android.index.prependSPSPPSToIDRFrames",
14373a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                &index);
14383a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
14393a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err == OK) {
14403a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            PrependSPSPPSToIDRFramesParams params;
14413a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            InitOMXParams(&params);
14423a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            params.bEnable = OMX_TRUE;
14433a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
14443a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            err = mOMX->setParameter(
14453a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                    mNode, index, &params, sizeof(params));
14463a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
14473a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
14483a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err != OK) {
14493a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            ALOGE("Encoder could not be configured to emit SPS/PPS before "
14503a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                  "IDR frames. (err %d)", err);
14513a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
14523a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            return err;
14533a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
14543a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    }
14553a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
1456308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // Only enable metadata mode on encoder output if encoder can prepend
1457308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // sps/pps to idr frames, since in metadata mode the bitstream is in an
1458308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // opaque handle, to which we don't have access.
1459308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t video = !strncasecmp(mime, "video/", 6);
14608db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    mIsVideo = video;
1461308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (encoder && video) {
1462308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS
1463308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && msg->findInt32("store-metadata-in-buffers-output", &storeMeta)
1464308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && storeMeta != 0);
1465308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1466308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, enable);
1467308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1468308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        if (err != OK) {
1469308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            ALOGE("[%s] storeMetaDataInBuffers (output) failed w/ err %d",
1470308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                mComponentName.c_str(), err);
1471308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = 0;
1472308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        } else {
1473308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = enable;
1474308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        }
1475a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
1476a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (!msg->findInt64(
1477a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    "repeat-previous-frame-after",
1478a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    &mRepeatFrameDelayUs)) {
1479a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            mRepeatFrameDelayUs = -1ll;
1480a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
148194ee4b708acfa941581160b267afb79192b1d816Chong Zhang
148294ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (!msg->findInt64("max-pts-gap-to-encoder", &mMaxPtsGapUs)) {
14832c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mMaxPtsGapUs = -1ll;
14842c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
14852c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
148637b2b389139ed638831e49708c947863eef631efRonghua Wu        if (!msg->findFloat("max-fps-to-encoder", &mMaxFps)) {
148737b2b389139ed638831e49708c947863eef631efRonghua Wu            mMaxFps = -1;
148837b2b389139ed638831e49708c947863eef631efRonghua Wu        }
148937b2b389139ed638831e49708c947863eef631efRonghua Wu
14902c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (!msg->findInt64("time-lapse", &mTimePerCaptureUs)) {
14912c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mTimePerCaptureUs = -1ll;
149294ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
149372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
149472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (!msg->findInt32(
149572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    "create-input-buffers-suspended",
149672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    (int32_t*)&mCreateInputBuffersSuspended)) {
149772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mCreateInputBuffersSuspended = false;
149872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
1499308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    }
1500308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
15013a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar    // NOTE: we only use native window for video decoders
1502054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    sp<RefBase> obj;
15030d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    bool haveNativeWindow = msg->findObject("native-window", &obj)
15043a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            && obj != NULL && video && !encoder;
1505054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mStoreMetaDataInOutputBuffers = false;
1506011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar    mLegacyAdaptiveExperiment = false;
1507e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if (video && !encoder) {
1508e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        inputFormat->setInt32("adaptive-playback", false);
15091713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang
15101713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        int32_t usageProtected;
15111713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        if (msg->findInt32("protected", &usageProtected) && usageProtected) {
15121713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            if (!haveNativeWindow) {
15131713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang                ALOGE("protected output buffers must be sent to an ANativeWindow");
15141713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang                return PERMISSION_DENIED;
15151713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            }
15161713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            mFlags |= kFlagIsGrallocUsageProtected;
15171713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
15181713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        }
1519e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
15203a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar    if (haveNativeWindow) {
15211de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar        sp<ANativeWindow> nativeWindow =
15221de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar            static_cast<ANativeWindow *>(static_cast<Surface *>(obj.get()));
15235a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
15246597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        // START of temporary support for automatic FRC - THIS WILL BE REMOVED
15256597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        int32_t autoFrc;
15266597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        if (msg->findInt32("auto-frc", &autoFrc)) {
15276597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            bool enabled = autoFrc;
15286597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            OMX_CONFIG_BOOLEANTYPE config;
15296597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            InitOMXParams(&config);
15306597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            config.bEnabled = (OMX_BOOL)enabled;
15316597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            status_t temp = mOMX->setConfig(
15326597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                    mNode, (OMX_INDEXTYPE)OMX_IndexConfigAutoFramerateConversion,
15336597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                    &config, sizeof(config));
15346597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            if (temp == OK) {
15356597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                outputFormat->setInt32("auto-frc", enabled);
15366597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            } else if (enabled) {
15376597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                ALOGI("codec does not support requested auto-frc (err %d)", temp);
15386597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            }
15396597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        }
15406597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        // END of temporary support for automatic FRC
15416597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar
15425a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        int32_t tunneled;
15435a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        if (msg->findInt32("feature-tunneled-playback", &tunneled) &&
15445a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            tunneled != 0) {
15455a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            ALOGI("Configuring TUNNELED video playback.");
1546ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            mTunneled = true;
15475a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
154897827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad            int32_t audioHwSync = 0;
154997827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad            if (!msg->findInt32("audio-hw-sync", &audioHwSync)) {
15505a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGW("No Audio HW Sync provided for video tunnel");
15515a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            }
15525a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            err = configureTunneledVideoPlayback(audioHwSync, nativeWindow);
15535a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (err != OK) {
155497827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad                ALOGE("configureTunneledVideoPlayback(%d,%p) failed!",
15555a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        audioHwSync, nativeWindow.get());
15565a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                return err;
1557fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
1558fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1559d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            int32_t maxWidth = 0, maxHeight = 0;
1560d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            if (msg->findInt32("max-width", &maxWidth) &&
1561d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    msg->findInt32("max-height", &maxHeight)) {
1562d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad
1563d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                err = mOMX->prepareForAdaptivePlayback(
1564d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                        mNode, kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight);
1565d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                if (err != OK) {
1566d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    ALOGW("[%s] prepareForAdaptivePlayback failed w/ err %d",
1567d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                            mComponentName.c_str(), err);
15683a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    // allow failure
15693a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    err = OK;
1570d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                } else {
1571d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("max-width", maxWidth);
1572d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("max-height", maxHeight);
1573d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("adaptive-playback", true);
1574d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                }
1575d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            }
15765a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        } else {
1577ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            ALOGV("Configuring CPU controlled video playback.");
1578ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            mTunneled = false;
1579ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
15803fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // Explicity reset the sideband handle of the window for
15813fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // non-tunneled video in case the window was previously used
15823fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // for a tunneled video playback.
15833fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            err = native_window_set_sideband_stream(nativeWindow.get(), NULL);
15843fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            if (err != OK) {
15853fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad                ALOGE("set_sideband_stream(NULL) failed! (err %d).", err);
15863fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad                return err;
15873fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            }
15883fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad
15895a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            // Always try to enable dynamic output buffers on native surface
15905a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            err = mOMX->storeMetaDataInBuffers(
15915a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    mNode, kPortIndexOutput, OMX_TRUE);
15925a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (err != OK) {
15935a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d",
1594fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        mComponentName.c_str(), err);
1595e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
15965a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // if adaptive playback has been requested, try JB fallback
15975a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // NOTE: THIS FALLBACK MECHANISM WILL BE REMOVED DUE TO ITS
15985a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // LARGE MEMORY REQUIREMENT
15995a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
16005a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // we will not do adaptive playback on software accessed
16015a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // surfaces as they never had to respond to changes in the
16025a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // crop window, and we don't trust that they will be able to.
16035a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                int usageBits = 0;
16045a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                bool canDoAdaptivePlayback;
16055a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
16065a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                if (nativeWindow->query(
16075a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        nativeWindow.get(),
16085a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        NATIVE_WINDOW_CONSUMER_USAGE_BITS,
16095a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        &usageBits) != OK) {
16105a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    canDoAdaptivePlayback = false;
16115a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                } else {
16125a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    canDoAdaptivePlayback =
16135a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        (usageBits &
16145a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                                (GRALLOC_USAGE_SW_READ_MASK |
16155a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                                 GRALLOC_USAGE_SW_WRITE_MASK)) == 0;
16165a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                }
16175a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
16185a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                int32_t maxWidth = 0, maxHeight = 0;
16195a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                if (canDoAdaptivePlayback &&
16205a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        msg->findInt32("max-width", &maxWidth) &&
16215a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        msg->findInt32("max-height", &maxHeight)) {
16225a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    ALOGV("[%s] prepareForAdaptivePlayback(%dx%d)",
16235a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mComponentName.c_str(), maxWidth, maxHeight);
16245a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
16255a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    err = mOMX->prepareForAdaptivePlayback(
16265a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mNode, kPortIndexOutput, OMX_TRUE, maxWidth,
16275a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            maxHeight);
16285a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    ALOGW_IF(err != OK,
16295a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            "[%s] prepareForAdaptivePlayback failed w/ err %d",
16305a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mComponentName.c_str(), err);
16315a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
16325a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    if (err == OK) {
16335a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("max-width", maxWidth);
16345a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("max-height", maxHeight);
16355a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("adaptive-playback", true);
16365a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    }
1637e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
16385a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // allow failure
16395a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                err = OK;
16405a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            } else {
16415a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGV("[%s] storeMetaDataInBuffers succeeded",
16425a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        mComponentName.c_str());
16435a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                mStoreMetaDataInOutputBuffers = true;
1644011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                mLegacyAdaptiveExperiment = ADebug::isExperimentEnabled(
1645011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                        "legacy-adaptive", !msg->contains("no-experiments"));
1646011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
16475a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                inputFormat->setInt32("adaptive-playback", true);
1648fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
16490167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber
16505a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            int32_t push;
16515a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (msg->findInt32("push-blank-buffers-on-shutdown", &push)
16525a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    && push != 0) {
16535a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
16545a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            }
16550167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        }
1656e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang
1657e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        int32_t rotationDegrees;
1658e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        if (msg->findInt32("rotation-degrees", &rotationDegrees)) {
1659e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            mRotationDegrees = rotationDegrees;
1660e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        } else {
1661e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            mRotationDegrees = 0;
1662e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        }
1663054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1664054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1665308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (video) {
16663a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // determine need for software renderer
16673a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        bool usingSwRenderer = false;
16683a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (haveNativeWindow && mComponentName.startsWith("OMX.google.")) {
16693a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            usingSwRenderer = true;
16703a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            haveNativeWindow = false;
16713a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
16723a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
16735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (encoder) {
16745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupVideoEncoder(mime, msg);
16755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
16760d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            err = setupVideoDecoder(mime, msg, haveNativeWindow);
16775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16783a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
16793a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (err != OK) {
16803a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            return err;
16813a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
16823a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
16833a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (haveNativeWindow) {
16841de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar            mNativeWindow = static_cast<Surface *>(obj.get());
16853a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
16863a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
16873a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // initialize native window now to get actual output format
16883a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // TODO: this is needed for some encoders even though they don't use native window
1689777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        err = initNativeWindow();
1690777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        if (err != OK) {
1691777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return err;
1692777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        }
16933a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
16943a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // fallback for devices that do not handle flex-YUV for native buffers
16953a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (haveNativeWindow) {
16963a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            int32_t requestedColorFormat = OMX_COLOR_FormatUnused;
16973a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            if (msg->findInt32("color-format", &requestedColorFormat) &&
16983a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    requestedColorFormat == OMX_COLOR_FormatYUV420Flexible) {
1699777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                status_t err = getPortFormat(kPortIndexOutput, outputFormat);
1700777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (err != OK) {
1701777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return err;
1702777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
17033a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                int32_t colorFormat = OMX_COLOR_FormatUnused;
17043a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                OMX_U32 flexibleEquivalent = OMX_COLOR_FormatUnused;
1705777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (!outputFormat->findInt32("color-format", &colorFormat)) {
1706777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGE("ouptut port did not have a color format (wrong domain?)");
1707777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return BAD_VALUE;
1708777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
17093a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                ALOGD("[%s] Requested output format %#x and got %#x.",
17103a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        mComponentName.c_str(), requestedColorFormat, colorFormat);
17113a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                if (!isFlexibleColorFormat(
17123a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                                mOMX, mNode, colorFormat, haveNativeWindow, &flexibleEquivalent)
17133a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        || flexibleEquivalent != (OMX_U32)requestedColorFormat) {
17143a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    // device did not handle flex-YUV request for native window, fall back
17153a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    // to SW renderer
17163a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    ALOGI("[%s] Falling back to software renderer", mComponentName.c_str());
17173a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    mNativeWindow.clear();
17183a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    haveNativeWindow = false;
17193a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    usingSwRenderer = true;
17203a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    if (mStoreMetaDataInOutputBuffers) {
17213a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, OMX_FALSE);
17223a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        mStoreMetaDataInOutputBuffers = false;
17233a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        // TODO: implement adaptive-playback support for bytebuffer mode.
17243a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        // This is done by SW codecs, but most HW codecs don't support it.
17253a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        inputFormat->setInt32("adaptive-playback", false);
17263a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
17273a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    if (err == OK) {
17283a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        err = mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
17293a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
17303a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    if (mFlags & kFlagIsGrallocUsageProtected) {
17313a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        // fallback is not supported for protected playback
17323a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        err = PERMISSION_DENIED;
17333a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    } else if (err == OK) {
17343a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        err = setupVideoDecoder(mime, msg, false);
17353a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
17363a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                }
17373a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            }
17383a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
17393a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
17403a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (usingSwRenderer) {
17413a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            outputFormat->setInt32("using-sw-renderer", 1);
17423a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
174342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
174442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        int32_t numChannels, sampleRate;
174542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        if (!msg->findInt32("channel-count", &numChannels)
174642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
174742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // Since we did not always check for these, leave them optional
174842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // and have the decoder figure it all out.
174942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = OK;
175042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        } else {
175142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = setupRawAudioFormat(
175242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    encoder ? kPortIndexInput : kPortIndexOutput,
175342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    sampleRate,
175442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    numChannels);
175542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        }
1756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
1757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t numChannels, sampleRate;
17585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)
17595778822d86b0337407514b9372562b86edfa91cdAndreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
17605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
17615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
1762aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            int32_t isADTS, aacProfile;
1763b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            int32_t sbrMode;
17648045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            int32_t maxOutputChannelCount;
17652965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            int32_t pcmLimiterEnable;
17668045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            drcParams_t drc;
1767ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            if (!msg->findInt32("is-adts", &isADTS)) {
1768ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                isADTS = 0;
1769ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
1770aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (!msg->findInt32("aac-profile", &aacProfile)) {
1771aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                aacProfile = OMX_AUDIO_AACObjectNull;
1772aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
1773b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            if (!msg->findInt32("aac-sbr-mode", &sbrMode)) {
1774b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                sbrMode = -1;
1775b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            }
1776ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
17778045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-max-output-channel_count", &maxOutputChannelCount)) {
17788045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                maxOutputChannelCount = -1;
17798045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
17802965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            if (!msg->findInt32("aac-pcm-limiter-enable", &pcmLimiterEnable)) {
17812965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                // value is unknown
17822965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                pcmLimiterEnable = -1;
17832965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            }
17848045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-encoded-target-level", &drc.encodedTargetLevel)) {
17858045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
17868045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.encodedTargetLevel = -1;
17878045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
17888045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-cut-level", &drc.drcCut)) {
17898045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
17908045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.drcCut = -1;
17918045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
17928045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-boost-level", &drc.drcBoost)) {
17938045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
17948045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.drcBoost = -1;
17958045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
17968045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-heavy-compression", &drc.heavyCompression)) {
17978045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
17988045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.heavyCompression = -1;
17998045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
18008045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-target-ref-level", &drc.targetRefLevel)) {
18018045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
18028045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.targetRefLevel = -1;
18038045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
18048045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi
1805ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            err = setupAACCodec(
18064471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    encoder, numChannels, sampleRate, bitRate, aacProfile,
18072965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                    isADTS != 0, sbrMode, maxOutputChannelCount, drc,
18082965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                    pcmLimiterEnable);
18095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
1810729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
18115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
1812729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
18135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
1814729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
1815729de186450f78c099637e1fce743fe531862c52Andreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
1816729de186450f78c099637e1fce743fe531862c52Andreas Huber        // These are PCM-like formats with a fixed sample rate but
1817729de186450f78c099637e1fce743fe531862c52Andreas Huber        // a variable number of channels.
1818729de186450f78c099637e1fce743fe531862c52Andreas Huber
1819729de186450f78c099637e1fce743fe531862c52Andreas Huber        int32_t numChannels;
18205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)) {
18215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
18225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
182317c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            int32_t sampleRate;
182417c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            if (!msg->findInt32("sample-rate", &sampleRate)) {
182517c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen                sampleRate = 8000;
182617c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            }
182717c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            err = setupG711Codec(encoder, sampleRate, numChannels);
18285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18292f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
1830ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        int32_t numChannels = 0, sampleRate = 0, compressionLevel = -1;
18312f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (encoder &&
18322f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                (!msg->findInt32("channel-count", &numChannels)
18332f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                        || !msg->findInt32("sample-rate", &sampleRate))) {
18342f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("missing channel count or sample rate for FLAC encoder");
18352f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            err = INVALID_OPERATION;
18362f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        } else {
18372f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            if (encoder) {
1838516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                if (!msg->findInt32(
1839cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                            "complexity", &compressionLevel) &&
1840cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                    !msg->findInt32(
1841516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                            "flac-compression-level", &compressionLevel)) {
1842cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                    compressionLevel = 5; // default FLAC compression level
18432f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel < 0) {
1844516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1845516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 0",
1846516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
18472f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 0;
18482f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel > 8) {
1849516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1850516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 8",
1851516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
18522f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 8;
18532f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                }
18542f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            }
1855516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            err = setupFlacCodec(
1856516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    encoder, numChannels, sampleRate, compressionLevel);
18572f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
1858ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
1859ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        int32_t numChannels, sampleRate;
1860ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        if (encoder
1861ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("channel-count", &numChannels)
1862ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
1863ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = INVALID_OPERATION;
1864ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        } else {
1865ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
1866ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        }
186797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AC3)) {
186897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t numChannels;
186997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t sampleRate;
187097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        if (!msg->findInt32("channel-count", &numChannels)
187197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                || !msg->findInt32("sample-rate", &sampleRate)) {
187297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = INVALID_OPERATION;
187397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        } else {
187497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = setupAC3Codec(encoder, numChannels, sampleRate);
187597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        }
18768a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_EAC3)) {
18778a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        int32_t numChannels;
18788a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        int32_t sampleRate;
18798a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        if (!msg->findInt32("channel-count", &numChannels)
18808a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                || !msg->findInt32("sample-rate", &sampleRate)) {
18818a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            err = INVALID_OPERATION;
18828a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        } else {
18838a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            err = setupEAC3Codec(encoder, numChannels, sampleRate);
18848a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        }
18855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1886729de186450f78c099637e1fce743fe531862c52Andreas Huber
18874471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    if (err != OK) {
18884471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber        return err;
18894471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    }
18904471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber
18918b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
18928b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderDelay = 0;
18938b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
18949806555d3930be43e11106281dee354820ac1c88Andreas Huber
18958b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
18968b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderPadding = 0;
18978b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
18988b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen
18999806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (msg->findInt32("channel-mask", &mChannelMask)) {
19009806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = true;
19019806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else {
19029806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = false;
19039806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
19049806555d3930be43e11106281dee354820ac1c88Andreas Huber
1905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t maxInputSize;
1906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (msg->findInt32("max-input-size", &maxInputSize)) {
19075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
1908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
19095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
1910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
19115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19128b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    int32_t priority;
19138b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    if (msg->findInt32("priority", &priority)) {
19148b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu        err = setPriority(priority);
19158b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    }
19168b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu
1917ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    int32_t rateInt = -1;
1918ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    float rateFloat = -1;
1919ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (!msg->findFloat("operating-rate", &rateFloat)) {
1920ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        msg->findInt32("operating-rate", &rateInt);
1921ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        rateFloat = (float)rateInt;  // 16MHz (FLINTMAX) is OK for upper bound.
1922ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
1923ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (rateFloat > 0) {
1924ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        err = setOperatingRate(rateFloat, video);
1925ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
1926ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu
19274e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    mBaseOutputFormat = outputFormat;
19284e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar
1929777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    err = getPortFormat(kPortIndexInput, inputFormat);
1930777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (err == OK) {
1931777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        err = getPortFormat(kPortIndexOutput, outputFormat);
1932777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        if (err == OK) {
1933777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            mInputFormat = inputFormat;
1934777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            mOutputFormat = outputFormat;
1935777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        }
1936777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
19375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
1938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
19408b806ea894ca098366629458bfdd1df4866afcdfRonghua Wustatus_t ACodec::setPriority(int32_t priority) {
19418b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    if (priority < 0) {
19428b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu        return BAD_VALUE;
19438b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    }
19448b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    OMX_PARAM_U32TYPE config;
19458b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    InitOMXParams(&config);
19468b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    config.nU32 = (OMX_U32)priority;
19478b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    status_t temp = mOMX->setConfig(
19488b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu            mNode, (OMX_INDEXTYPE)OMX_IndexConfigPriority,
19498b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu            &config, sizeof(config));
19508b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    if (temp != OK) {
19518b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu        ALOGI("codec does not support config priority (err %d)", temp);
19528b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    }
19538b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    return OK;
19548b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu}
19558b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu
1956ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wustatus_t ACodec::setOperatingRate(float rateFloat, bool isVideo) {
1957ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (rateFloat < 0) {
1958ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        return BAD_VALUE;
1959ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
1960ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    OMX_U32 rate;
1961ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (isVideo) {
1962ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        if (rateFloat > 65535) {
1963ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            return BAD_VALUE;
1964ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        }
1965ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        rate = (OMX_U32)(rateFloat * 65536.0f + 0.5f);
1966ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    } else {
1967ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        if (rateFloat > UINT_MAX) {
1968ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            return BAD_VALUE;
1969ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        }
1970ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        rate = (OMX_U32)(rateFloat);
1971ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
1972ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    OMX_PARAM_U32TYPE config;
1973ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    InitOMXParams(&config);
1974ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    config.nU32 = rate;
1975ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    status_t err = mOMX->setConfig(
1976ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            mNode, (OMX_INDEXTYPE)OMX_IndexConfigOperatingRate,
1977ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            &config, sizeof(config));
1978ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (err != OK) {
1979ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        ALOGI("codec does not support config operating rate (err %d)", err);
1980ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
1981ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    return OK;
1982ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu}
1983ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu
1984f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
1985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
1987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
1988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (def.nBufferSize >= size) {
1997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
1998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nBufferSize = size;
2001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
2003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->getParameter(
2010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2016777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (def.nBufferSize < size) {
2017777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("failed to set min buffer size to %zu (is still %u)", size, def.nBufferSize);
2018777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return FAILED_TRANSACTION;
2019777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
2020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
20245778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::selectAudioPortFormat(
20255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
20265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_AUDIO_PARAM_PORTFORMATTYPE format;
20275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&format);
20285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    format.nPortIndex = portIndex;
20305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (OMX_U32 index = 0;; ++index) {
20315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        format.nIndex = index;
20325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
20345778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioPortFormat,
20355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &format, sizeof(format));
20365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
20385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
20395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (format.eEncoding == desiredFormat) {
20425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
20435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
20475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format));
20485778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
20495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20505778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAACCodec(
2051aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        bool encoder, int32_t numChannels, int32_t sampleRate,
20528045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        int32_t bitRate, int32_t aacProfile, bool isADTS, int32_t sbrMode,
20532965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang        int32_t maxOutputChannelCount, const drcParams_t& drc,
20542965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang        int32_t pcmLimiterEnable) {
2055ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (encoder && isADTS) {
2056ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return -EINVAL;
2057ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
2058ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
20595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setupRawAudioFormat(
20605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
20615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sampleRate,
20625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            numChannels);
20635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (encoder) {
20695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
20705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
20725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
20735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
20765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
20775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = kPortIndexOutput;
20785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
20805778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
20815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
20835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
20845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.bFlagErrorConcealment = OMX_TRUE;
20875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
20885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
20905778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
20915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
20935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
20945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
20975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&profile);
20985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nPortIndex = kPortIndexOutput;
20995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
21015778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
21025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
21045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
21055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nChannels = numChannels;
21085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eChannelMode =
21105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (numChannels == 1)
21115778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
21125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nSampleRate = sampleRate;
21145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nBitRate = bitRate;
21155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAudioBandWidth = 0;
21165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nFrameLength = 0;
21175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACtools = OMX_AUDIO_AACToolAll;
21185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACERtools = OMX_AUDIO_AACERNone;
2119aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
21205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
2121b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        switch (sbrMode) {
2122b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 0:
2123b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // disable sbr
2124b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
2125b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
2126b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2127b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 1:
2128b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable single-rate sbr
2129b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
2130b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
2131b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2132b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 2:
2133b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable dual-rate sbr
2134b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
2135b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
2136b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2137b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case -1:
2138b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable both modes -> the codec will decide which mode should be used
2139b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
2140b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
2141b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2142b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        default:
2143b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // unsupported sbr mode
2144b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            return BAD_VALUE;
2145b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        }
2146b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi
21475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
21495778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
21505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
21525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
21535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_AUDIO_PARAM_AACPROFILETYPE profile;
2159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&profile);
2160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nPortIndex = kPortIndexInput;
2161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
21625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
2163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
2164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nChannels = numChannels;
2170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nSampleRate = sampleRate;
2171ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2172ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    profile.eAACStreamFormat =
2173ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        isADTS
2174ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            ? OMX_AUDIO_AACStreamFormatMP4ADTS
2175ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            : OMX_AUDIO_AACStreamFormatMP4FF;
2176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
21778045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    OMX_AUDIO_PARAM_ANDROID_AACPRESENTATIONTYPE presentation;
21788045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nMaxOutputChannels = maxOutputChannelCount;
21798045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nDrcCut = drc.drcCut;
21808045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nDrcBoost = drc.drcBoost;
21818045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nHeavyCompression = drc.heavyCompression;
21828045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nTargetReferenceLevel = drc.targetRefLevel;
21838045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nEncodedTargetLevel = drc.encodedTargetLevel;
21842965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang    presentation.nPCMLimiterEnable = pcmLimiterEnable;
21858045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi
21868045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    status_t res = mOMX->setParameter(mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
21878045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    if (res == OK) {
21888045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        // optional parameters, will not cause configuration failure
21898045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        mOMX->setParameter(mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAacPresentation,
21908045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                &presentation, sizeof(presentation));
21918045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    } else {
21928045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        ALOGW("did not set AudioAndroidAacPresentation due to error %d when setting AudioAac", res);
21938045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    }
21948045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    return res;
21955778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
2196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
219797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryustatus_t ACodec::setupAC3Codec(
219897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        bool encoder, int32_t numChannels, int32_t sampleRate) {
219997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    status_t err = setupRawAudioFormat(
220097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
220197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
220297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
220397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
220497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
220597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
220697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (encoder) {
220797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        ALOGW("AC3 encoding is not supported.");
220897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return INVALID_OPERATION;
220997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
221097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
221197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    OMX_AUDIO_PARAM_ANDROID_AC3TYPE def;
221297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    InitOMXParams(&def);
221397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nPortIndex = kPortIndexInput;
221497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
221597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    err = mOMX->getParameter(
221697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
221797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
221897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
221997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
222097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
222197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
222297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
222397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
222497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
222597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nChannels = numChannels;
222697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nSampleRate = sampleRate;
222797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
222897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    return mOMX->setParameter(
222997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
223097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
223197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
223297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
223397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu}
223497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
22358a4728966dc9c78e21c3c93a927707e93c05e5e0Rachadstatus_t ACodec::setupEAC3Codec(
22368a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        bool encoder, int32_t numChannels, int32_t sampleRate) {
22378a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    status_t err = setupRawAudioFormat(
22388a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
22398a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
22408a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (err != OK) {
22418a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return err;
22428a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
22438a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
22448a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (encoder) {
22458a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        ALOGW("EAC3 encoding is not supported.");
22468a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return INVALID_OPERATION;
22478a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
22488a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
22498a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    OMX_AUDIO_PARAM_ANDROID_EAC3TYPE def;
22508a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    InitOMXParams(&def);
22518a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nPortIndex = kPortIndexInput;
22528a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
22538a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    err = mOMX->getParameter(
22548a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            mNode,
22558a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
22568a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            &def,
22578a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            sizeof(def));
22588a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
22598a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (err != OK) {
22608a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return err;
22618a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
22628a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
22638a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nChannels = numChannels;
22648a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nSampleRate = sampleRate;
22658a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
22668a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    return mOMX->setParameter(
22678a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            mNode,
22688a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
22698a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            &def,
22708a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            sizeof(def));
22718a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad}
22728a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
22735778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
22745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        bool isAMRWB, int32_t bps) {
22755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (isAMRWB) {
22765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 6600) {
22775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB0;
22785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 8850) {
22795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB1;
22805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 12650) {
22815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB2;
22825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 14250) {
22835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB3;
22845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 15850) {
22855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB4;
22865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 18250) {
22875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB5;
22885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 19850) {
22895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB6;
22905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 23050) {
22915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB7;
22925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 23850 bps
22955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeWB8;
22965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {  // AMRNB
22975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 4750) {
22985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB0;
22995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5150) {
23005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB1;
23015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5900) {
23025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB2;
23035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 6700) {
23045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB3;
23055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7400) {
23065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB4;
23075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7950) {
23085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB5;
23095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 10200) {
23105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB6;
23115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 12200 bps
23145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeNB7;
23155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
23185778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
2319729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_AMRTYPE def;
2320729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
23215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
2322729de186450f78c099637e1fce743fe531862c52Andreas Huber
2323729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err =
2324729de186450f78c099637e1fce743fe531862c52Andreas Huber        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
2325729de186450f78c099637e1fce743fe531862c52Andreas Huber
2326729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2327729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2328729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2329729de186450f78c099637e1fce743fe531862c52Andreas Huber
2330729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
23315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
23325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
23345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
2335729de186450f78c099637e1fce743fe531862c52Andreas Huber
23365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
23375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
23385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2339729de186450f78c099637e1fce743fe531862c52Andreas Huber
23405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupRawAudioFormat(
23415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
23425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            isWAMR ? 16000 : 8000 /* sampleRate */,
23435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            1 /* numChannels */);
2344729de186450f78c099637e1fce743fe531862c52Andreas Huber}
2345729de186450f78c099637e1fce743fe531862c52Andreas Huber
234617c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissenstatus_t ACodec::setupG711Codec(bool encoder, int32_t sampleRate, int32_t numChannels) {
2347777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (encoder) {
2348777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return INVALID_OPERATION;
2349777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
23505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2351729de186450f78c099637e1fce743fe531862c52Andreas Huber    return setupRawAudioFormat(
235217c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            kPortIndexInput, sampleRate, numChannels);
2353729de186450f78c099637e1fce743fe531862c52Andreas Huber}
2354729de186450f78c099637e1fce743fe531862c52Andreas Huber
23552f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivistatus_t ACodec::setupFlacCodec(
23562f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
23572f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
23582f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder) {
23592f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        OMX_AUDIO_PARAM_FLACTYPE def;
23602f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        InitOMXParams(&def);
23612f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nPortIndex = kPortIndexOutput;
23622f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
23632f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        // configure compression level
23642f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        status_t err = mOMX->getParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
23652f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
23662f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
23672f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
23682f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
23692f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nCompressionLevel = compressionLevel;
23702f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        err = mOMX->setParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
23712f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
23722f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
23732f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
23742f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
23752f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
23762f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
23772f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    return setupRawAudioFormat(
23782f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            encoder ? kPortIndexInput : kPortIndexOutput,
23792f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            sampleRate,
23802f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            numChannels);
23812f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi}
23822f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
2383729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t ACodec::setupRawAudioFormat(
2384729de186450f78c099637e1fce743fe531862c52Andreas Huber        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
2385729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
2386729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
2387729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.nPortIndex = portIndex;
2388729de186450f78c099637e1fce743fe531862c52Andreas Huber
2389729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err = mOMX->getParameter(
2390729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2391729de186450f78c099637e1fce743fe531862c52Andreas Huber
2392729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2393729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2394729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2395729de186450f78c099637e1fce743fe531862c52Andreas Huber
2396729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
2397729de186450f78c099637e1fce743fe531862c52Andreas Huber
2398729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->setParameter(
2399729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2400729de186450f78c099637e1fce743fe531862c52Andreas Huber
2401729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2402729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2403729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2404729de186450f78c099637e1fce743fe531862c52Andreas Huber
2405729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
2406729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&pcmParams);
2407729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nPortIndex = portIndex;
2408729de186450f78c099637e1fce743fe531862c52Andreas Huber
2409729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->getParameter(
2410729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
2411729de186450f78c099637e1fce743fe531862c52Andreas Huber
2412729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2413729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2414729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2415729de186450f78c099637e1fce743fe531862c52Andreas Huber
2416729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nChannels = numChannels;
2417729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.eNumData = OMX_NumericalDataSigned;
2418729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.bInterleaved = OMX_TRUE;
2419729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nBitPerSample = 16;
2420729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nSamplingRate = sampleRate;
2421729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
2422729de186450f78c099637e1fce743fe531862c52Andreas Huber
2423c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber    if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
2424c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber        return OMX_ErrorNone;
2425729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2426729de186450f78c099637e1fce743fe531862c52Andreas Huber
2427729de186450f78c099637e1fce743fe531862c52Andreas Huber    return mOMX->setParameter(
2428729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
2429729de186450f78c099637e1fce743fe531862c52Andreas Huber}
2430729de186450f78c099637e1fce743fe531862c52Andreas Huber
24315a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachadstatus_t ACodec::configureTunneledVideoPlayback(
243297827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad        int32_t audioHwSync, const sp<ANativeWindow> &nativeWindow) {
24335a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    native_handle_t* sidebandHandle;
24345a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
24355a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    status_t err = mOMX->configureVideoTunnelMode(
24365a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            mNode, kPortIndexOutput, OMX_TRUE, audioHwSync, &sidebandHandle);
24375a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    if (err != OK) {
24385a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        ALOGE("configureVideoTunnelMode failed! (err %d).", err);
24395a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        return err;
24405a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    }
24415a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
24425a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    err = native_window_set_sideband_stream(nativeWindow.get(), sidebandHandle);
24435a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    if (err != OK) {
24445a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        ALOGE("native_window_set_sideband_stream(%p) failed! (err %d).",
24455a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                sidebandHandle, err);
24465a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        return err;
24475a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    }
24485a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
24495a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    return OK;
24505a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad}
24515a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
2452f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoPortFormatType(
2453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
2454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_VIDEO_CODINGTYPE compressionFormat,
24550d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        OMX_COLOR_FORMATTYPE colorFormat,
24560d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        bool usingNativeBuffers) {
2457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
2458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
2459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = portIndex;
2460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
2461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool found = false;
2462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 index = 0;
2464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (;;) {
2465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        format.nIndex = index;
2466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->getParameter(
2467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamVideoPortFormat,
2468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &format, sizeof(format));
2469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
2471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return err;
2472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2474229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        // substitute back flexible color format to codec supported format
2475229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        OMX_U32 flexibleEquivalent;
24760d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (compressionFormat == OMX_VIDEO_CodingUnused
24770d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && isFlexibleColorFormat(
24780d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        mOMX, mNode, format.eColorFormat, usingNativeBuffers, &flexibleEquivalent)
24790d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && colorFormat == flexibleEquivalent) {
2480229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            ALOGI("[%s] using color format %#x in place of %#x",
2481229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                    mComponentName.c_str(), format.eColorFormat, colorFormat);
2482229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            colorFormat = format.eColorFormat;
2483229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
2484229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
2485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The following assertion is violated by TI's video decoder.
2486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // CHECK_EQ(format.nIndex, index);
2487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
2489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexInput
2490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && colorFormat == format.eColorFormat) {
2491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eCompressionFormat does not seem right.
2492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
2493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
2494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexOutput
2496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && compressionFormat == format.eCompressionFormat) {
2497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eColorFormat does not seem right.
2498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
2499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
2500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (format.eCompressionFormat == compressionFormat
2504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && format.eColorFormat == colorFormat) {
2505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            found = true;
2506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ++index;
2510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!found) {
2513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return UNKNOWN_ERROR;
2514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->setParameter(
2517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
2518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
2519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
2521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
25230d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// Set optimal output format. OMX component lists output formats in the order
25240d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// of preference, but this got more complicated since the introduction of flexible
25250d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// YUV formats. We support a legacy behavior for applications that do not use
25260d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// surface output, do not specify an output format, but expect a "usable" standard
25270d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// OMX format. SW readable and standard formats must be flex-YUV.
25280d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar//
25290d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// Suggested preference order:
25300d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal format for texture rendering (mediaplayer behavior)
25310d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal SW readable & texture renderable format (flex-YUV support)
25320d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal SW readable non-renderable format (flex-YUV bytebuffer support)
25330d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - legacy "usable" standard formats
25340d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar//
25350d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// For legacy support, we prefer a standard format, but will settle for a SW readable
25360d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// flex-YUV format.
25370d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnarstatus_t ACodec::setSupportedOutputFormat(bool getLegacyFlexibleFormat) {
25380d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    OMX_VIDEO_PARAM_PORTFORMATTYPE format, legacyFormat;
2539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
2540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = kPortIndexOutput;
2541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
25420d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    InitOMXParams(&legacyFormat);
25430d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    // this field will change when we find a suitable legacy format
25440d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    legacyFormat.eColorFormat = OMX_COLOR_FormatUnused;
2545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
25460d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    for (OMX_U32 index = 0; ; ++index) {
25470d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        format.nIndex = index;
25480d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        status_t err = mOMX->getParameter(
25490d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                mNode, OMX_IndexParamVideoPortFormat,
25500d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                &format, sizeof(format));
25510d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (err != OK) {
25520d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            // no more formats, pick legacy format if found
25530d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            if (legacyFormat.eColorFormat != OMX_COLOR_FormatUnused) {
25540d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                 memcpy(&format, &legacyFormat, sizeof(format));
25550d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                 break;
25560d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            }
25570d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            return err;
25580d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
25590d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (format.eCompressionFormat != OMX_VIDEO_CodingUnused) {
25600d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            return OMX_ErrorBadParameter;
25610d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
25620d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (!getLegacyFlexibleFormat) {
25630d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            break;
25640d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
25650d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        // standard formats that were exposed to users before
25660d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (format.eColorFormat == OMX_COLOR_FormatYUV420Planar
25670d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_COLOR_FormatYUV420PackedPlanar
25680d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar
25690d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_COLOR_FormatYUV420PackedSemiPlanar
25700d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar) {
25710d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            break;
25720d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
25730d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        // find best legacy non-standard format
25740d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        OMX_U32 flexibleEquivalent;
25750d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (legacyFormat.eColorFormat == OMX_COLOR_FormatUnused
25760d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && isFlexibleColorFormat(
25770d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        mOMX, mNode, format.eColorFormat, false /* usingNativeBuffers */,
25780d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        &flexibleEquivalent)
25790d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && flexibleEquivalent == OMX_COLOR_FormatYUV420Flexible) {
25800d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            memcpy(&legacyFormat, &format, sizeof(format));
25810d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
25820d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    }
2583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mOMX->setParameter(
2584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
2585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
2586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2588e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic const struct VideoCodingMapEntry {
2589e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    const char *mMime;
2590e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    OMX_VIDEO_CODINGTYPE mVideoCodingType;
2591e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber} kVideoCodingMapEntry[] = {
2592e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC },
25932472b1c0d63454e5d90a982bd6c555de6c3127bdRachad    { MEDIA_MIMETYPE_VIDEO_HEVC, OMX_VIDEO_CodingHEVC },
2594e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 },
2595e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 },
2596e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 },
259794705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 },
259894705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 },
2599e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber};
2600e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
26015778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic status_t GetVideoCodingTypeFromMime(
26025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
2603e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
2604e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
2605e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
2606e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) {
2607e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *codingType = kVideoCodingMapEntry[i].mVideoCodingType;
2608e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
2609e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
2610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2612e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    *codingType = OMX_VIDEO_CodingUnused;
2613e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2614e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
2615e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
2616e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2617e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic status_t GetMimeTypeForVideoCoding(
2618e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        OMX_VIDEO_CODINGTYPE codingType, AString *mime) {
2619e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
2620e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
2621e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
2622e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) {
2623e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *mime = kVideoCodingMapEntry[i].mMime;
2624e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
2625e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
2626e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
2627e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2628e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    mime->clear();
2629e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2630e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
26315778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
26325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26335778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoDecoder(
26340d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        const char *mime, const sp<AMessage> &msg, bool haveNativeWindow) {
263589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    int32_t width, height;
263689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    if (!msg->findInt32("width", &width)
263789869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            || !msg->findInt32("height", &height)) {
263889869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        return INVALID_OPERATION;
263989869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    }
264089869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar
26415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
26425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
26435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
26455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
26465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
2649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
2650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
265589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    int32_t tmp;
265689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    if (msg->findInt32("color-format", &tmp)) {
265789869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        OMX_COLOR_FORMATTYPE colorFormat =
265889869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            static_cast<OMX_COLOR_FORMATTYPE>(tmp);
265989869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        err = setVideoPortFormatType(
26600d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                kPortIndexOutput, OMX_VIDEO_CodingUnused, colorFormat, haveNativeWindow);
266189869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        if (err != OK) {
266289869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            ALOGW("[%s] does not support color format %d",
266389869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar                  mComponentName.c_str(), colorFormat);
26640d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            err = setSupportedOutputFormat(!haveNativeWindow /* getLegacyFlexibleFormat */);
266589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        }
266689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    } else {
26670d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        err = setSupportedOutputFormat(!haveNativeWindow /* getLegacyFlexibleFormat */);
266889869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    }
2669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
267478b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    int32_t frameRateInt;
267578b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    float frameRateFloat;
267678b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    if (!msg->findFloat("frame-rate", &frameRateFloat)) {
267778b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        if (!msg->findInt32("frame-rate", &frameRateInt)) {
267878b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            frameRateInt = -1;
267978b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        }
268078b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        frameRateFloat = (float)frameRateInt;
268178b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    }
268278b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad
2683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
268478b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            kPortIndexInput, width, height, compressionFormat, frameRateFloat);
2685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
2691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
2692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
27005778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) {
27015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
27025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("color-format", &tmp)) {
27035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
27045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_COLOR_FORMATTYPE colorFormat =
27075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        static_cast<OMX_COLOR_FORMATTYPE>(tmp);
27085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setVideoPortFormatType(
27105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
27115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
27135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support color format %d",
27145778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str(), colorFormat);
27155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
27175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Input port configuration */
27205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
27225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&def);
27235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
27255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexInput;
27275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
27295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
27305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
27325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
27335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t width, height, bitrate;
27365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("width", &width)
27375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("height", &height)
27385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("bitrate", &bitrate)) {
27395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
27405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
27435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
27445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t stride;
27465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("stride", &stride)) {
27475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        stride = width;
27485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nStride = stride;
27515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t sliceHeight;
27535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("slice-height", &sliceHeight)) {
27545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sliceHeight = height;
27555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nSliceHeight = sliceHeight;
27585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
27605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
27625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
27635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
27645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
27655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
27665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
27675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
27682c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        mTimePerFrameUs = (int64_t) (1000000.0f / frameRate);
27695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
27725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
2773a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    // this is redundant as it was already set up in setVideoPortFormatType
2774a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    // FIXME for now skip this only for flexible YUV formats
2775a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    if (colorFormat != OMX_COLOR_FormatYUV420Flexible) {
2776a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar        video_def->eColorFormat = colorFormat;
2777a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    }
27785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
27805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
27815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
27835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set input port definition parameters.",
27845778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
27855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
27875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Output port configuration */
27905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
27925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
27935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
27955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
27965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
27995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
28005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
28025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support compression format %d",
28035778822d86b0337407514b9372562b86edfa91cdAndreas Huber             mComponentName.c_str(), compressionFormat);
28045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
28065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexOutput;
28095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
28115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
28125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
28145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
28155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
28185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
28195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = 0;
28205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nBitrate = bitrate;
28215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = compressionFormat;
28225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = OMX_COLOR_FormatUnused;
28235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
28255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
28265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
28285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set output port definition parameters.",
28295778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
28305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
28325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (compressionFormat) {
28355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingMPEG4:
28365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupMPEG4EncoderParameters(msg);
28375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
28385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingH263:
28405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupH263EncoderParameters(msg);
28415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
28425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingAVC:
28445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupAVCEncoderParameters(msg);
28455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
28465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2847c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        case OMX_VIDEO_CodingHEVC:
2848c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            err = setupHEVCEncoderParameters(msg);
2849c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            break;
2850c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
285189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP8:
285289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP9:
285389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            err = setupVPXEncoderParameters(msg);
285489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            break;
285589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
28565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
28575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
28585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGI("setupVideoEncoder succeeded");
28615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
28635778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
28645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28650dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dongstatus_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) {
28660dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    OMX_VIDEO_PARAM_INTRAREFRESHTYPE params;
28670dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    InitOMXParams(&params);
28680dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.nPortIndex = kPortIndexOutput;
28690dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
28700dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode);
28710dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
28720dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic ||
28730dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
28740dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
28750dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) {
28760dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
28770dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
28780dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nCirMBs = mbs;
28790dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
28800dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
28810dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive ||
28820dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
28830dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
28840dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) {
28850dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
28860dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
28870dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirMBs = mbs;
28880dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
28890dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t ref;
28900dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) {
28910dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
28920dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
28930dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirRef = ref;
28940dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
28950dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
28960dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = mOMX->setParameter(
28970dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            mNode, OMX_IndexParamVideoIntraRefresh,
28980dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            &params, sizeof(params));
28990dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    return err;
29000dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong}
29010dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
29025778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
29035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (iFramesInterval < 0) {
29045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0xFFFFFFFF;
29055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (iFramesInterval == 0) {
29065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0;
29075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_U32 ret = frameRate * iFramesInterval;
29095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return ret;
29105778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
29115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
291296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatic OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) {
291396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    int32_t tmp;
291496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    if (!msg->findInt32("bitrate-mode", &tmp)) {
291596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        return OMX_Video_ControlRateVariable;
291696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    }
291796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
291896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp);
291996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber}
292096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
29215778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
29225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
29235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
29245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
29255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
29265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
292896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
292996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
29305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
29315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
29325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
29335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
29345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
29355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
29365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
29375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
29405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&mpeg4type);
29415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPortIndex = kPortIndexOutput;
29425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
29445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
29455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
29475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
29485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nSliceHeaderSpacing = 0;
29515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bSVH = OMX_FALSE;
29525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bGov = OMX_FALSE;
29535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nAllowedPictureTypes =
29555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
29565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
29585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mpeg4type.nPFrames == 0) {
29595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
29605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nBFrames = 0;
29625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nIDCVLCThreshold = 0;
29635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bACPred = OMX_TRUE;
29645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nMaxPacketSize = 256;
29655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nTimeIncRes = 1000;
29665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nHeaderExtension = 0;
29675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bReversibleVLC = OMX_FALSE;
29685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
29705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
29715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
29725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
29735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
29745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
29755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
29775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
29795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
29805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
29815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
29835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
29845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
29875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
29885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
29905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
29915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
299396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
29945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
29965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
29975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
30005778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
30015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30025778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
30035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
30045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
30055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
30065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
30075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
30085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
300996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
301096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
30115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
30125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
30135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
30145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
30155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
30165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
30175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
30185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
30195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_H263TYPE h263type;
30215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h263type);
30225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPortIndex = kPortIndexOutput;
30235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
30255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
30265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
30285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
30295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
30305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nAllowedPictureTypes =
30325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
30335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
30355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h263type.nPFrames == 0) {
30365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
30375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
30385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nBFrames = 0;
30395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
30415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
30425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
30435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
30445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
30455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
30465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
30485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
30505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
30515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
30525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
30545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
30555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
30565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bPLUSPTYPEAllowed = OMX_FALSE;
30585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bForceRoundingTypeToZero = OMX_FALSE;
30595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPictureHeaderRepetition = 0;
30605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nGOBHeaderInterval = 0;
30615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
30635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
30645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
30665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
30675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
30685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
306996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
30705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
30725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
30735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
30745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
30765778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
30775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3078a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar// static
3079a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnarint /* OMX_VIDEO_AVCLEVELTYPE */ ACodec::getAVCLevelFor(
3080a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        int width, int height, int rate, int bitrate,
3081a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        OMX_VIDEO_AVCPROFILETYPE profile) {
3082a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    // convert bitrate to main/baseline profile kbps equivalent
3083a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    switch (profile) {
3084a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        case OMX_VIDEO_AVCProfileHigh10:
3085a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 3000); break;
3086a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        case OMX_VIDEO_AVCProfileHigh:
3087a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 1250); break;
3088a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        default:
3089a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 1000); break;
3090a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    }
3091a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
3092a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    // convert size and rate to MBs
3093a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    width = divUp(width, 16);
3094a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    height = divUp(height, 16);
3095a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    int mbs = width * height;
3096a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    rate *= mbs;
3097a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    int maxDimension = max(width, height);
3098a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
3099a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    static const int limits[][5] = {
3100a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        /*   MBps     MB   dim  bitrate        level */
3101a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    1485,    99,  28,     64, OMX_VIDEO_AVCLevel1  },
3102a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    1485,    99,  28,    128, OMX_VIDEO_AVCLevel1b },
3103a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    3000,   396,  56,    192, OMX_VIDEO_AVCLevel11 },
3104a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    6000,   396,  56,    384, OMX_VIDEO_AVCLevel12 },
3105a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   11880,   396,  56,    768, OMX_VIDEO_AVCLevel13 },
3106a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   11880,   396,  56,   2000, OMX_VIDEO_AVCLevel2  },
3107a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   19800,   792,  79,   4000, OMX_VIDEO_AVCLevel21 },
3108a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   20250,  1620, 113,   4000, OMX_VIDEO_AVCLevel22 },
3109a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   40500,  1620, 113,  10000, OMX_VIDEO_AVCLevel3  },
3110a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  108000,  3600, 169,  14000, OMX_VIDEO_AVCLevel31 },
3111a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  216000,  5120, 202,  20000, OMX_VIDEO_AVCLevel32 },
3112a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  245760,  8192, 256,  20000, OMX_VIDEO_AVCLevel4  },
3113a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  245760,  8192, 256,  50000, OMX_VIDEO_AVCLevel41 },
3114a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  522240,  8704, 263,  50000, OMX_VIDEO_AVCLevel42 },
3115a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  589824, 22080, 420, 135000, OMX_VIDEO_AVCLevel5  },
3116a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  983040, 36864, 543, 240000, OMX_VIDEO_AVCLevel51 },
3117a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        { 2073600, 36864, 543, 240000, OMX_VIDEO_AVCLevel52 },
3118a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    };
3119a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
3120a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    for (size_t i = 0; i < ARRAY_SIZE(limits); i++) {
3121a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        const int (&limit)[5] = limits[i];
3122a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        if (rate <= limit[0] && mbs <= limit[1] && maxDimension <= limit[2]
3123a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar                && bitrate <= limit[3]) {
3124a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            return limit[4];
3125a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        }
3126a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    }
3127a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    return 0;
3128a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar}
3129a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
31305778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
31315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
31325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
31335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
31345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
31355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
31365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
313796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
313896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
31395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
31405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
31415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
31425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
31435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
31445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
31455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
31465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
31475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31480dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = OK;
31490dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    int32_t intraRefreshMode = 0;
31500dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) {
31510dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode);
31520dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (err != OK) {
31530dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
31540dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong                    err, intraRefreshMode);
31550dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return err;
31560dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
31570dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
31580dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
31595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_AVCTYPE h264type;
31605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h264type);
31615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nPortIndex = kPortIndexOutput;
31625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31630dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    err = mOMX->getParameter(
31645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
31655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
31675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
31685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
31695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nAllowedPictureTypes =
31715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
31725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
31745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
31755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
31765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
31775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
31785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
31795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
31815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
31835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
31845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
31855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
31875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
31885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
31895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // XXX
31917c25df82dfc8bbedb58608242f0d923a4594bb14James Dong    if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) {
31927c25df82dfc8bbedb58608242f0d923a4594bb14James Dong        ALOGW("Use baseline profile instead of %d for AVC recording",
31937c25df82dfc8bbedb58608242f0d923a4594bb14James Dong            h264type.eProfile);
31945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
31955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
31965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
31985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nSliceHeaderSpacing = 0;
31995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bUseHadamard = OMX_TRUE;
32005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefFrames = 1;
32015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nBFrames = 0;
32025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
32035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (h264type.nPFrames == 0) {
32045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
32055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
32065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx10ActiveMinus1 = 0;
32075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx11ActiveMinus1 = 0;
32085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bEntropyCodingCABAC = OMX_FALSE;
32095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bWeightedPPrediction = OMX_FALSE;
32105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bconstIpred = OMX_FALSE;
32115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirect8x8Inference = OMX_FALSE;
32125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirectSpatialTemporal = OMX_FALSE;
32135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nCabacInitIdc = 0;
32145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
32155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.nBFrames != 0) {
32175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
32185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
32195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableUEP = OMX_FALSE;
32215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableFMO = OMX_FALSE;
32225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableASO = OMX_FALSE;
32235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableRS = OMX_FALSE;
32245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bFrameMBsOnly = OMX_TRUE;
32255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bMBAFF = OMX_FALSE;
32265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
32275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
32295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
32305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
32325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
32335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
32345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
323596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return configureBitrate(bitrate, bitrateMode);
32365778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
32375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3238c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachadstatus_t ACodec::setupHEVCEncoderParameters(const sp<AMessage> &msg) {
3239c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    int32_t bitrate, iFrameInterval;
3240c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findInt32("bitrate", &bitrate)
3241c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
3242c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return INVALID_OPERATION;
3243c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
3244c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3245c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
3246c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3247c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    float frameRate;
3248c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findFloat("frame-rate", &frameRate)) {
3249c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t tmp;
3250c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("frame-rate", &tmp)) {
3251c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
3252c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
3253c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        frameRate = (float)tmp;
3254c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
3255c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3256c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_PARAM_HEVCTYPE hevcType;
3257c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    InitOMXParams(&hevcType);
3258c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    hevcType.nPortIndex = kPortIndexOutput;
3259c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3260c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    status_t err = OK;
3261c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    err = mOMX->getParameter(
3262c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
3263c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
3264c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
3265c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
3266c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3267c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    int32_t profile;
3268c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (msg->findInt32("profile", &profile)) {
3269c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t level;
3270c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("level", &level)) {
3271c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
3272c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
3273c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3274c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        err = verifySupportForProfileAndLevel(profile, level);
3275c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (err != OK) {
3276c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return err;
3277c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
3278c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3279c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eProfile = static_cast<OMX_VIDEO_HEVCPROFILETYPE>(profile);
3280c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eLevel = static_cast<OMX_VIDEO_HEVCLEVELTYPE>(level);
3281c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
3282c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3283c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    // TODO: Need OMX structure definition for setting iFrameInterval
3284c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3285c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    err = mOMX->setParameter(
3286c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
3287c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
3288c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
3289c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
3290c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3291c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    return configureBitrate(bitrate, bitrateMode);
3292c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad}
3293c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
329489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huberstatus_t ACodec::setupVPXEncoderParameters(const sp<AMessage> &msg) {
329589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    int32_t bitrate;
32964154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    int32_t iFrameInterval = 0;
32974154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    size_t tsLayers = 0;
32984154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE pattern =
32994154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        OMX_VIDEO_VPXTemporalLayerPatternNone;
33004154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    static const uint32_t kVp8LayerRateAlloction
33014154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS]
33024154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS] = {
33034154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        {100, 100, 100},  // 1 layer
33044154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 60, 100, 100},  // 2 layers {60%, 40%}
33054154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 40,  60, 100},  // 3 layers {40%, 20%, 40%}
33064154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    };
330789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    if (!msg->findInt32("bitrate", &bitrate)) {
330889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        return INVALID_OPERATION;
330989b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    }
33104154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    msg->findInt32("i-frame-interval", &iFrameInterval);
331189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
331289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
331389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
33144154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    float frameRate;
33154154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (!msg->findFloat("frame-rate", &frameRate)) {
33164154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        int32_t tmp;
33174154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (!msg->findInt32("frame-rate", &tmp)) {
33184154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            return INVALID_OPERATION;
33194154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
33204154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        frameRate = (float)tmp;
33214154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
33224154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
33234154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    AString tsSchema;
33244154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (msg->findString("ts-schema", &tsSchema)) {
33254154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (tsSchema == "webrtc.vp8.1-layer") {
33264154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
33274154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 1;
33284154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else if (tsSchema == "webrtc.vp8.2-layer") {
33294154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
33304154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 2;
33314154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else if (tsSchema == "webrtc.vp8.3-layer") {
33324154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
33334154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 3;
33344154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else {
33354154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            ALOGW("Unsupported ts-schema [%s]", tsSchema.c_str());
33364154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
33374154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
33384154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
33394154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
33404154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    InitOMXParams(&vp8type);
33414154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    vp8type.nPortIndex = kPortIndexOutput;
33424154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    status_t err = mOMX->getParameter(
33434154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
33444154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            &vp8type, sizeof(vp8type));
33454154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
33464154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (err == OK) {
33474154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (iFrameInterval > 0) {
33484154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nKeyFrameInterval = setPFramesSpacing(iFrameInterval, frameRate);
33494154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
33504154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.eTemporalPattern = pattern;
33514154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.nTemporalLayerCount = tsLayers;
33524154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (tsLayers > 0) {
33534154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            for (size_t i = 0; i < OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS; i++) {
33544154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                vp8type.nTemporalLayerBitrateRatio[i] =
33554154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                    kVp8LayerRateAlloction[tsLayers - 1][i];
33564154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            }
33574154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
33584154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (bitrateMode == OMX_Video_ControlRateConstant) {
33594154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMinQuantizer = 2;
33604154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMaxQuantizer = 63;
33614154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
33624154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
33634154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        err = mOMX->setParameter(
33644154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
33654154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                &vp8type, sizeof(vp8type));
33664154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (err != OK) {
33674154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            ALOGW("Extended VP8 parameters set failed: %d", err);
33684154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
33694154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
33704154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
337189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    return configureBitrate(bitrate, bitrateMode);
337289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber}
337389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
33745778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::verifySupportForProfileAndLevel(
33755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t profile, int32_t level) {
33765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
33775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&params);
33785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    params.nPortIndex = kPortIndexOutput;
33795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (params.nProfileIndex = 0;; ++params.nProfileIndex) {
33815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
33825778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode,
33835778822d86b0337407514b9372562b86edfa91cdAndreas Huber                OMX_IndexParamVideoProfileLevelQuerySupported,
33845778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &params,
33855778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sizeof(params));
33865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
33885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
33895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
33905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
33925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
33935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (profile == supportedProfile && level <= supportedLevel) {
33955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OK;
33965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
33975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
33985778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
33995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
340096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatus_t ACodec::configureBitrate(
340196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) {
34025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
34035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&bitrateType);
34045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
34055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
34075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
34085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
34095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
34115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
34125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
34135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
341496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    bitrateType.eControlRate = bitrateMode;
34155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nTargetBitrate = bitrate;
34165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
34185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
34195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
34205778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
34215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34225778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupErrorCorrectionParameters() {
34235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
34245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&errorCorrectionType);
34255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nPortIndex = kPortIndexOutput;
34265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
34285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
34295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
34305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
34325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OK;  // Optional feature. Ignore this failure
34335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
34345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableHEC = OMX_FALSE;
34365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableResync = OMX_TRUE;
34375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nResynchMarkerSpacing = 256;
34385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
34395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableRVLC = OMX_FALSE;
34405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
34425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
34435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
34445778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
34455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3446f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoFormatOnPort(
3447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
344878b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat,
344978b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        float frameRate) {
3450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
3451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
3452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
3453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
3455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
3457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
3458777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (err != OK) {
3459777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return err;
3460777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
3461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
3463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // XXX Need a (much) better heuristic to compute input buffer sizes.
3464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const size_t X = 64 * 1024;
3465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (def.nBufferSize < X) {
3466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.nBufferSize = X;
3467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3470777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (def.eDomain != OMX_PortDomainVideo) {
3471777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("expected video port, got %s(%d)", asString(def.eDomain), def.eDomain);
3472777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return FAILED_TRANSACTION;
3473777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
3474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameWidth = width;
3476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameHeight = height;
3477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
3479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eCompressionFormat = compressionFormat;
3480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eColorFormat = OMX_COLOR_FormatUnused;
348178b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        if (frameRate >= 0) {
348278b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
348378b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        }
3484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
3487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
3488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
3490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3492f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::initNativeWindow() {
3493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL) {
3494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
3495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
3498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
3499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3501d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Hubersize_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
3502d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    size_t n = 0;
3503d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
3504d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
3505d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        const BufferInfo &info = mBuffers[portIndex].itemAt(i);
3506d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
3507d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
3508d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            ++n;
3509d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        }
3510d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    }
3511d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
3512d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    return n;
3513d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber}
3514d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
35157e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubersize_t ACodec::countBuffersOwnedByNativeWindow() const {
35167e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    size_t n = 0;
35177e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
35187e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
35197e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
35207e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
35217e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
35227e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            ++n;
35237e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        }
35247e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
35257e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
35267e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    return n;
35277e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
35287e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
35297e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubervoid ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
35307e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (mNativeWindow == NULL) {
35317e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        return;
35327e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
35337e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
3534e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    while (countBuffersOwnedByNativeWindow() > mNumUndequeuedBuffers
35357e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            && dequeueBufferFromNativeWindow() != NULL) {
3536c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        // these buffers will be submitted as regular buffers; account for this
3537c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        if (mStoreMetaDataInOutputBuffers && mMetaDataBuffersToSubmit > 0) {
3538c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar            --mMetaDataBuffersToSubmit;
3539c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        }
35407e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
35417e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
35427e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
3543f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs(
3544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
3545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
3546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
3547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus != BufferInfo::OWNED_BY_US
3549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3550609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGV("[%s] Buffer %u on port %u still has status %d",
3551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mComponentName.c_str(),
3552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info->mBufferID, portIndex, info->mStatus);
3553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
3554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3560f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs() {
3561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return allYourBuffersAreBelongToUs(kPortIndexInput)
3562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        && allYourBuffersAreBelongToUs(kPortIndexOutput);
3563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3565f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::deferMessage(const sp<AMessage> &msg) {
3566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.push_back(msg);
3567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3569f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::processDeferredMessages() {
3570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> > queue = mDeferredQueue;
3571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.clear();
3572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> >::iterator it = queue.begin();
3574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while (it != queue.end()) {
3575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        onMessageReceived(*it++);
3576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
357903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar// static
3580229d242665c612fd97431d1e7ac004823b47f181Lajos Molnarbool ACodec::describeDefaultColorFormat(DescribeColorFormatParams &params) {
358103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    MediaImage &image = params.sMediaImage;
358203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    memset(&image, 0, sizeof(image));
358303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
358403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mType = MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
358503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mNumPlanes = 0;
358603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
358703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    const OMX_COLOR_FORMATTYPE fmt = params.eColorFormat;
358803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mWidth = params.nFrameWidth;
358903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mHeight = params.nFrameHeight;
359003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
359103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    // only supporting YUV420
359203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    if (fmt != OMX_COLOR_FormatYUV420Planar &&
359303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        fmt != OMX_COLOR_FormatYUV420PackedPlanar &&
359403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        fmt != OMX_COLOR_FormatYUV420SemiPlanar &&
35955a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        fmt != OMX_COLOR_FormatYUV420PackedSemiPlanar &&
35965a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        fmt != HAL_PIXEL_FORMAT_YV12) {
359703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        ALOGW("do not know color format 0x%x = %d", fmt, fmt);
3598229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return false;
359903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    }
360003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
3601b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    // TEMPORARY FIX for some vendors that advertise sliceHeight as 0
3602b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    if (params.nStride != 0 && params.nSliceHeight == 0) {
3603b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        ALOGW("using sliceHeight=%u instead of what codec advertised (=0)",
3604b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar                params.nFrameHeight);
3605b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        params.nSliceHeight = params.nFrameHeight;
3606b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    }
3607b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar
3608b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    // we need stride and slice-height to be non-zero
3609b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    if (params.nStride == 0 || params.nSliceHeight == 0) {
3610b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        ALOGW("cannot describe color format 0x%x = %d with stride=%u and sliceHeight=%u",
3611b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar                fmt, fmt, params.nStride, params.nSliceHeight);
3612b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        return false;
3613b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    }
3614b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar
361503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    // set-up YUV format
361603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mType = MediaImage::MEDIA_IMAGE_TYPE_YUV;
361703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mNumPlanes = 3;
361803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mBitDepth = 8;
361903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mOffset = 0;
362003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mColInc = 1;
362103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mRowInc = params.nStride;
362203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mHorizSubsampling = 1;
362303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mVertSubsampling = 1;
362403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
36255a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar    switch ((int)fmt) {
36265a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        case HAL_PIXEL_FORMAT_YV12:
36275a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            if (params.bUsingNativeBuffers) {
36285a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                size_t ystride = align(params.nStride, 16);
36295a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                size_t cstride = align(params.nStride / 2, 16);
36305a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.Y].mRowInc = ystride;
36315a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
36325a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mOffset = ystride * params.nSliceHeight;
36335a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mColInc = 1;
36345a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mRowInc = cstride;
36355a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mHorizSubsampling = 2;
36365a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mVertSubsampling = 2;
36375a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
36385a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mOffset = image.mPlane[image.V].mOffset
36395a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                        + (cstride * params.nSliceHeight / 2);
36405a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mColInc = 1;
36415a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mRowInc = cstride;
36425a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mHorizSubsampling = 2;
36435a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mVertSubsampling = 2;
36445a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                break;
36455a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            } else {
36465a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                // fall through as YV12 is used for YUV420Planar by some codecs
36475a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            }
36485a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
36495a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        case OMX_COLOR_FormatYUV420Planar:
365003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420PackedPlanar:
365103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight;
365203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mColInc = 1;
365303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mRowInc = params.nStride / 2;
365403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mHorizSubsampling = 2;
365503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mVertSubsampling = 2;
365603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
365703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset
365803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    + (params.nStride * params.nSliceHeight / 4);
365903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mColInc = 1;
366003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mRowInc = params.nStride / 2;
366103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mHorizSubsampling = 2;
366203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mVertSubsampling = 2;
366303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            break;
366403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
366503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420SemiPlanar:
366603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            // FIXME: NV21 for sw-encoder, NV12 for decoder and hw-encoder
366703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420PackedSemiPlanar:
366803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            // NV12
366903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight;
367003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mColInc = 2;
367103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mRowInc = params.nStride;
367203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mHorizSubsampling = 2;
367303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mVertSubsampling = 2;
367403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
367503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset + 1;
367603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mColInc = 2;
367703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mRowInc = params.nStride;
367803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mHorizSubsampling = 2;
367903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mVertSubsampling = 2;
368003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            break;
368103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
368203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        default:
368303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            TRESPASS();
368403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    }
3685229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    return true;
3686229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar}
3687229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3688229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar// static
3689229d242665c612fd97431d1e7ac004823b47f181Lajos Molnarbool ACodec::describeColorFormat(
3690229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        const sp<IOMX> &omx, IOMX::node_id node,
3691229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        DescribeColorFormatParams &describeParams)
3692229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar{
3693229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    OMX_INDEXTYPE describeColorFormatIndex;
3694229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    if (omx->getExtensionIndex(
3695229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            node, "OMX.google.android.index.describeColorFormat",
3696229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            &describeColorFormatIndex) != OK ||
3697229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        omx->getParameter(
3698229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            node, describeColorFormatIndex,
3699229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            &describeParams, sizeof(describeParams)) != OK) {
3700229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return describeDefaultColorFormat(describeParams);
3701229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    }
3702229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    return describeParams.sMediaImage.mType !=
3703229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
3704229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar}
3705229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3706229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar// static
3707229d242665c612fd97431d1e7ac004823b47f181Lajos Molnarbool ACodec::isFlexibleColorFormat(
3708229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar         const sp<IOMX> &omx, IOMX::node_id node,
37090d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar         uint32_t colorFormat, bool usingNativeBuffers, OMX_U32 *flexibleEquivalent) {
3710229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    DescribeColorFormatParams describeParams;
3711229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    InitOMXParams(&describeParams);
3712229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.eColorFormat = (OMX_COLOR_FORMATTYPE)colorFormat;
3713229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    // reasonable dummy values
3714229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nFrameWidth = 128;
3715229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nFrameHeight = 128;
3716229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nStride = 128;
3717229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nSliceHeight = 128;
37180d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    describeParams.bUsingNativeBuffers = (OMX_BOOL)usingNativeBuffers;
3719229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3720229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    CHECK(flexibleEquivalent != NULL);
3721229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3722229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    if (!describeColorFormat(omx, node, describeParams)) {
3723229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return false;
3724229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    }
3725229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3726229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    const MediaImage &img = describeParams.sMediaImage;
3727229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    if (img.mType == MediaImage::MEDIA_IMAGE_TYPE_YUV) {
3728229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        if (img.mNumPlanes != 3 ||
3729229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            img.mPlane[img.Y].mHorizSubsampling != 1 ||
3730229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            img.mPlane[img.Y].mVertSubsampling != 1) {
3731229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            return false;
3732229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
3733229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3734229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        // YUV 420
3735229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        if (img.mPlane[img.U].mHorizSubsampling == 2
3736229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.U].mVertSubsampling == 2
3737229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.V].mHorizSubsampling == 2
3738229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.V].mVertSubsampling == 2) {
3739229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            // possible flexible YUV420 format
3740229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            if (img.mBitDepth <= 8) {
3741229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar               *flexibleEquivalent = OMX_COLOR_FormatYUV420Flexible;
3742229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar               return true;
3743229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            }
3744229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
3745229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    }
3746229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    return false;
374703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar}
374803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
3749e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarstatus_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> &notify) {
3750777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    const char *niceIndex = portIndex == kPortIndexInput ? "input" : "output";
375131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
375231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    InitOMXParams(&def);
3753e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    def.nPortIndex = portIndex;
375431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3755777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    status_t err = mOMX->getParameter(mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
3756777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (err != OK) {
3757777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return err;
3758777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
375931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3760777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (def.eDir != (portIndex == kPortIndexOutput ? OMX_DirOutput : OMX_DirInput)) {
3761777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("unexpected dir: %s(%d) on %s port", asString(def.eDir), def.eDir, niceIndex);
3762777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return BAD_VALUE;
3763777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
376431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
376531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    switch (def.eDomain) {
376631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainVideo:
376731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
376831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
3769e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            switch ((int)videoDef->eCompressionFormat) {
3770e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_VIDEO_CodingUnused:
3771e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3772e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(mIsEncoder ^ (portIndex == kPortIndexOutput));
3773e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
3774e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3775e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("stride", videoDef->nStride);
3776e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("slice-height", videoDef->nSliceHeight);
3777e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("color-format", videoDef->eColorFormat);
3778e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
37790d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                    if (mNativeWindow == NULL) {
37800d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        DescribeColorFormatParams describeParams;
37810d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        InitOMXParams(&describeParams);
37820d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.eColorFormat = videoDef->eColorFormat;
37830d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nFrameWidth = videoDef->nFrameWidth;
37840d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nFrameHeight = videoDef->nFrameHeight;
37850d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nStride = videoDef->nStride;
37860d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nSliceHeight = videoDef->nSliceHeight;
37870d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.bUsingNativeBuffers = OMX_FALSE;
37880d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar
37890d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        if (describeColorFormat(mOMX, mNode, describeParams)) {
37900d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                            notify->setBuffer(
37910d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                    "image-data",
37920d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                    ABuffer::CreateAsCopy(
37930d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                            &describeParams.sMediaImage,
37940d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                            sizeof(describeParams.sMediaImage)));
37955a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
37965a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                            MediaImage *img = &describeParams.sMediaImage;
37975a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                            ALOGV("[%s] MediaImage { F(%zux%zu) @%zu+%zu+%zu @%zu+%zu+%zu @%zu+%zu+%zu }",
37985a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                                    mComponentName.c_str(), img->mWidth, img->mHeight,
37995a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                                    img->mPlane[0].mOffset, img->mPlane[0].mColInc, img->mPlane[0].mRowInc,
38005a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                                    img->mPlane[1].mOffset, img->mPlane[1].mColInc, img->mPlane[1].mRowInc,
38015a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                                    img->mPlane[2].mOffset, img->mPlane[2].mColInc, img->mPlane[2].mRowInc);
38020d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        }
380303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    }
380403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
380591a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                    if (portIndex != kPortIndexOutput) {
380691a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                        // TODO: also get input crop
380791a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                        break;
380891a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                    }
380991a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar
3810e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_CONFIG_RECTTYPE rect;
3811e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&rect);
381291a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                    rect.nPortIndex = portIndex;
3813e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3814e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    if (mOMX->getConfig(
381591a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                mNode,
381691a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                (portIndex == kPortIndexOutput ?
381791a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                        OMX_IndexConfigCommonOutputCrop :
381891a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                        OMX_IndexConfigCommonInputCrop),
3819e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &rect, sizeof(rect)) != OK) {
3820e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nLeft = 0;
3821e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nTop = 0;
3822e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nWidth = videoDef->nFrameWidth;
3823e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nHeight = videoDef->nFrameHeight;
3824e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    }
382531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3826777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (rect.nLeft < 0 ||
3827777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        rect.nTop < 0 ||
3828777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        rect.nLeft + rect.nWidth > videoDef->nFrameWidth ||
3829777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        rect.nTop + rect.nHeight > videoDef->nFrameHeight) {
3830777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        ALOGE("Wrong cropped rect (%d, %d) - (%u, %u) vs. frame (%u, %u)",
3831777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                rect.nLeft, rect.nTop,
3832777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                rect.nLeft + rect.nWidth, rect.nTop + rect.nHeight,
3833777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                videoDef->nFrameWidth, videoDef->nFrameHeight);
3834777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return BAD_VALUE;
3835777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
3836e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3837e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setRect(
3838577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            "crop",
3839577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nLeft,
3840577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nTop,
3841e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                            rect.nLeft + rect.nWidth - 1,
3842e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                            rect.nTop + rect.nHeight - 1);
3843e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3844e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3845e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
38464730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
38474730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP8:
38484730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP9:
38494730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                {
38504730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
38514730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    InitOMXParams(&vp8type);
38524730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    vp8type.nPortIndex = kPortIndexOutput;
38534730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    status_t err = mOMX->getParameter(
38544730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            mNode,
38554730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
38564730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            &vp8type,
38574730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            sizeof(vp8type));
38584730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
38594730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    if (err == OK) {
38604730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        AString tsSchema = "none";
38614730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        if (vp8type.eTemporalPattern
38624730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                == OMX_VIDEO_VPXTemporalLayerPatternWebRTC) {
38634730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            switch (vp8type.nTemporalLayerCount) {
38644730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 1:
38654730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
38664730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.1-layer";
38674730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
38684730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
38694730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 2:
38704730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
38714730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.2-layer";
38724730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
38734730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
38744730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 3:
38754730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
38764730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.3-layer";
38774730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
38784730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
38794730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                default:
38804730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
38814730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
38824730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
38834730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            }
38844730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        }
38854730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        notify->setString("ts-schema", tsSchema);
38864730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    }
38874730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    // Fall through to set up mime.
38884730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                }
38894730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
3890e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                default:
3891e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3892777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (mIsEncoder ^ (portIndex == kPortIndexOutput)) {
3893777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        // should be CodingUnused
3894777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        ALOGE("Raw port video compression format is %s(%d)",
3895777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                asString(videoDef->eCompressionFormat),
3896777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                videoDef->eCompressionFormat);
3897777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return BAD_VALUE;
3898777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
3899e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    AString mime;
3900e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    if (GetMimeTypeForVideoCoding(
3901e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        videoDef->eCompressionFormat, &mime) != OK) {
3902e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", "application/octet-stream");
3903e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    } else {
3904e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", mime.c_str());
3905e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    }
3906e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3907e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
390831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            }
3909e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("width", videoDef->nFrameWidth);
3910e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("height", videoDef->nFrameHeight);
39115a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            ALOGV("[%s] %s format is %s", mComponentName.c_str(),
39125a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                    portIndex == kPortIndexInput ? "input" : "output",
39135a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                    notify->debugString().c_str());
39145a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
391531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
391631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
391731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
391831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainAudio:
391931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
392031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
392131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
392297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            switch ((int)audioDef->eEncoding) {
3923e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingPCM:
3924e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3925e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_PCMMODETYPE params;
3926e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3927e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3928e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3929777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
3930777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, OMX_IndexParamAudioPcm, &params, sizeof(params));
3931777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
3932777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
3933777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
393414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
3935777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (params.nChannels <= 0
3936777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            || (params.nChannels != 1 && !params.bInterleaved)
3937777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            || params.nBitPerSample != 16u
3938777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            || params.eNumData != OMX_NumericalDataSigned
3939777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            || params.ePCMMode != OMX_AUDIO_PCMModeLinear) {
3940777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        ALOGE("unsupported PCM port: %u channels%s, %u-bit, %s(%d), %s(%d) mode ",
3941777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                params.nChannels,
3942777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                params.bInterleaved ? " interleaved" : "",
3943777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                params.nBitPerSample,
3944777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                asString(params.eNumData), params.eNumData,
3945777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                asString(params.ePCMMode), params.ePCMMode);
3946777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return FAILED_TRANSACTION;
3947777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
3948e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3949e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
3950e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
3951e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSamplingRate);
3952e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3953e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mChannelMaskPresent) {
3954e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("channel-mask", mChannelMask);
39558b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                    }
3956e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
39578b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                }
39589806555d3930be43e11106281dee354820ac1c88Andreas Huber
3959e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAAC:
3960e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3961e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AACPROFILETYPE params;
3962e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3963e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3964e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3965777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
3966777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, OMX_IndexParamAudioAac, &params, sizeof(params));
3967777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
3968777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
3969777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
3970e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3971e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
3972e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
3973e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
3974e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
3975e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
3976e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3977e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAMR:
3978e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3979e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AMRTYPE params;
3980e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3981e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
39829806555d3930be43e11106281dee354820ac1c88Andreas Huber
3983777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
3984777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, OMX_IndexParamAudioAmr, &params, sizeof(params));
3985777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
3986777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
3987777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
3988e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3989e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", 1);
3990e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) {
39910806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_WB);
3992e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 16000);
3993e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    } else {
39940806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
3995e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 8000);
3996e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
3997e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
3998e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
3999e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4000e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingFLAC:
4001e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
4002e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_FLACTYPE params;
4003e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
4004e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
4005e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4006777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4007777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, OMX_IndexParamAudioFlac, &params, sizeof(params));
4008777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4009777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4010777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4011e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4012e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC);
4013e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
4014e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
4015e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
4016e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
4017e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4018e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingMP3:
4019e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
4020e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_MP3TYPE params;
4021e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
4022e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
4023e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4024777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4025777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, OMX_IndexParamAudioMp3, &params, sizeof(params));
4026777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4027777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4028777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4029e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4030e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MPEG);
4031e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
4032e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
4033e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
4034e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
4035e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4036e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingVORBIS:
4037e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
4038e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_VORBISTYPE params;
4039e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
4040e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
4041e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4042777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4043777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, OMX_IndexParamAudioVorbis, &params, sizeof(params));
4044777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4045777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4046777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4047e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4048e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_VORBIS);
4049e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
4050e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
4051e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
4052e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
4053e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
405497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                case OMX_AUDIO_CodingAndroidAC3:
405597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                {
405697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    OMX_AUDIO_PARAM_ANDROID_AC3TYPE params;
405797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    InitOMXParams(&params);
4058e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
405997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
4060777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4061777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
4062777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            &params, sizeof(params));
4063777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4064777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4065777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
406697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
406797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AC3);
406897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("channel-count", params.nChannels);
406997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("sample-rate", params.nSampleRate);
407097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    break;
407197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                }
4072e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
40738a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                case OMX_AUDIO_CodingAndroidEAC3:
40748a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                {
40758a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    OMX_AUDIO_PARAM_ANDROID_EAC3TYPE params;
40768a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    InitOMXParams(&params);
40778a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    params.nPortIndex = portIndex;
40788a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
4079777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4080777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
4081777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            &params, sizeof(params));
4082777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4083777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4084777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
40858a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
40868a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_EAC3);
40878a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setInt32("channel-count", params.nChannels);
40888a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setInt32("sample-rate", params.nSampleRate);
40898a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    break;
40908a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                }
40918a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
40928c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                case OMX_AUDIO_CodingAndroidOPUS:
40938c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                {
40948c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    OMX_AUDIO_PARAM_ANDROID_OPUSTYPE params;
40958c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    InitOMXParams(&params);
40968c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    params.nPortIndex = portIndex;
40978c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
4098777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4099777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus,
4100777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            &params, sizeof(params));
4101777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4102777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4103777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
41048c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
41058c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_OPUS);
41068c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("channel-count", params.nChannels);
41078c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("sample-rate", params.nSampleRate);
41088c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    break;
41098c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                }
41108c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
411110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                case OMX_AUDIO_CodingG711:
411210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                {
411310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    OMX_AUDIO_PARAM_PCMMODETYPE params;
411410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    InitOMXParams(&params);
411510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    params.nPortIndex = portIndex;
411610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
4117777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4118777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioPcm, &params, sizeof(params));
4119777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4120777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4121777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
412210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
412310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    const char *mime = NULL;
412410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    if (params.ePCMMode == OMX_AUDIO_PCMModeMULaw) {
412510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_G711_MLAW;
412610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    } else if (params.ePCMMode == OMX_AUDIO_PCMModeALaw) {
412710d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_G711_ALAW;
412810d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    } else { // params.ePCMMode == OMX_AUDIO_PCMModeLinear
412910d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_RAW;
413010d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    }
413110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setString("mime", mime);
413210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setInt32("channel-count", params.nChannels);
413310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setInt32("sample-rate", params.nSamplingRate);
413410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    break;
413510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                }
413641d3f579d2c166984958263533284209b90c87d5Marco Nelissen
413741d3f579d2c166984958263533284209b90c87d5Marco Nelissen                case OMX_AUDIO_CodingGSMFR:
413841d3f579d2c166984958263533284209b90c87d5Marco Nelissen                {
41390806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    OMX_AUDIO_PARAM_PCMMODETYPE params;
414041d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    InitOMXParams(&params);
414141d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    params.nPortIndex = portIndex;
414241d3f579d2c166984958263533284209b90c87d5Marco Nelissen
4143777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4144777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                mNode, OMX_IndexParamAudioPcm, &params, sizeof(params));
4145777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4146777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4147777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
414841d3f579d2c166984958263533284209b90c87d5Marco Nelissen
414941d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MSGSM);
415041d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    notify->setInt32("channel-count", params.nChannels);
41510806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    notify->setInt32("sample-rate", params.nSamplingRate);
415241d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    break;
415310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                }
415410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
4155e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                default:
4156777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGE("Unsupported audio coding: %s(%d)\n",
4157777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            asString(audioDef->eEncoding), audioDef->eEncoding);
4158777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return BAD_TYPE;
4159e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
416031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
416131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
416231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
416331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        default:
4164777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("Unsupported domain: %s(%d)", asString(def.eDomain), def.eDomain);
4165777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return BAD_TYPE;
416631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    }
416731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4168e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    return OK;
4169e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar}
4170e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4171e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarvoid ACodec::sendFormatChange(const sp<AMessage> &reply) {
41724e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    sp<AMessage> notify = mBaseOutputFormat->dup();
4173e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    notify->setInt32("what", kWhatOutputFormatChanged);
4174e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4175777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (getPortFormat(kPortIndexOutput, notify) != OK) {
4176777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("[%s] Failed to get port format to send format change", mComponentName.c_str());
4177777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return;
4178777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
4179e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4180e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    AString mime;
4181e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK(notify->findString("mime", &mime));
4182e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4183e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    int32_t left, top, right, bottom;
4184e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if (mime == MEDIA_MIMETYPE_VIDEO_RAW &&
4185e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        mNativeWindow != NULL &&
4186e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->findRect("crop", &left, &top, &right, &bottom)) {
4187e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        // notify renderer of the crop change
4188e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        // NOTE: native window uses extended right-bottom coordinate
4189e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        reply->setRect("crop", left, top, right + 1, bottom + 1);
4190e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    } else if (mime == MEDIA_MIMETYPE_AUDIO_RAW &&
4191e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar               (mEncoderDelay || mEncoderPadding)) {
4192e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        int32_t channelCount;
4193e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        CHECK(notify->findInt32("channel-count", &channelCount));
4194e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        size_t frameSize = channelCount * sizeof(int16_t);
4195e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        if (mSkipCutBuffer != NULL) {
4196e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            size_t prevbufsize = mSkipCutBuffer->size();
4197e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            if (prevbufsize != 0) {
4198ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                ALOGW("Replacing SkipCutBuffer holding %zu bytes", prevbufsize);
4199e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            }
4200e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        }
4201e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        mSkipCutBuffer = new SkipCutBuffer(
4202e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                mEncoderDelay * frameSize,
4203e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                mEncoderPadding * frameSize);
4204e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
4205e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
420631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->post();
420731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
420831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mSentFormat = true;
420931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber}
421031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
42115778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
4212cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    sp<AMessage> notify = mNotify->dup();
4213d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatError);
4214251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    ALOGE("signalError(omxError %#x, internalError %d)", error, internalError);
4215251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
4216251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (internalError == UNKNOWN_ERROR) { // find better error code
4217251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        const status_t omxStatus = statusFromOMXError(error);
4218251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        if (omxStatus != 0) {
4219251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            internalError = omxStatus;
4220251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        } else {
4221251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            ALOGW("Invalid OMX error %#x", error);
4222251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        }
4223251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
42245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("err", internalError);
4225251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    notify->setInt32("actionCode", ACTION_CODE_FATAL); // could translate from OMX error.
4226cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->post();
4227cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber}
4228cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber
4229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4231eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberACodec::PortDescription::PortDescription() {
4232eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
4233eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4234496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t ACodec::requestIDRFrame() {
4235496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    if (!mIsEncoder) {
4236496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        return ERROR_UNSUPPORTED;
4237496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    }
4238496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4239496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    OMX_CONFIG_INTRAREFRESHVOPTYPE params;
4240496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    InitOMXParams(&params);
4241496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4242496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.nPortIndex = kPortIndexOutput;
4243496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.IntraRefreshVOP = OMX_TRUE;
4244496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4245496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    return mOMX->setConfig(
4246496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            mNode,
4247496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            OMX_IndexConfigVideoIntraVOPRefresh,
4248496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            &params,
4249496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            sizeof(params));
4250496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
4251496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4252eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubervoid ACodec::PortDescription::addBuffer(
4253eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        IOMX::buffer_id id, const sp<ABuffer> &buffer) {
4254eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBufferIDs.push_back(id);
4255eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBuffers.push_back(buffer);
4256eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
4257eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4258eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersize_t ACodec::PortDescription::countBuffers() {
4259eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.size();
4260eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
4261eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4262eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberIOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const {
4263eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.itemAt(index);
4264eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
4265eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4266eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const {
4267eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBuffers.itemAt(index);
4268eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
4269eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4270eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber////////////////////////////////////////////////////////////////////////////////
4271eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4272f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
4273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : AState(parentState),
4274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mCodec(codec) {
4275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4277ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas HuberACodec::BaseState::PortMode ACodec::BaseState::getPortMode(
4278ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
4279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return KEEP_BUFFERS;
4280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4282f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
4283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatInputBufferFilled:
4285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onInputBufferFilled(msg);
4287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatOutputBufferDrained:
4291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onOutputBufferDrained(msg);
4293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatOMXMessage:
4297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXMessage(msg);
4299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
43011dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        case ACodec::kWhatSetSurface:
43021dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        {
43031dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            sp<AReplyToken> replyID;
43041dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            CHECK(msg->senderAwaitsResponse(&replyID));
43051dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
43061dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            sp<RefBase> obj;
43071dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            CHECK(msg->findObject("surface", &obj));
43081dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
4309011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            status_t err =
4310011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                ADebug::isExperimentEnabled("legacy-setsurface") ? BAD_VALUE :
4311011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                        mCodec->handleSetSurface(static_cast<Surface *>(obj.get()));
43121dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
43131dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            sp<AMessage> response = new AMessage;
43141dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            response->setInt32("err", err);
43151dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            response->postReply(replyID);
43161dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            break;
43171dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
43181dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
43197cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
4320d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        case ACodec::kWhatUsePersistentInputSurface:
43217cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
43227cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
4323251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            // This may result in an app illegal state exception.
43247cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            ALOGE("Message 0x%x was not handled", msg->what());
43257cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
43267cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            return true;
43277cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
43287cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4329ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        case ACodec::kWhatOMXDied:
4330ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        {
4331251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            // This will result in kFlagSawMediaServerDie handling in MediaCodec.
4332ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            ALOGE("OMX/mediaserver died, signalling error!");
4333ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT);
4334ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            break;
4335ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        }
4336ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
433730358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        case ACodec::kWhatReleaseCodecInstance:
433830358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        {
433930358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            ALOGI("[%s] forcing the release of codec",
434030358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar                    mCodec->mComponentName.c_str());
434130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            status_t err = mCodec->mOMX->freeNode(mCodec->mNode);
434230358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            ALOGE_IF("[%s] failed to release codec instance: err=%d",
434330358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar                       mCodec->mComponentName.c_str(), err);
434430358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            sp<AMessage> notify = mCodec->mNotify->dup();
434530358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
434630358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            notify->post();
434730358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            break;
434830358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        }
434930358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar
4350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
4352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4357f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
4358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t type;
4359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findInt32("type", &type));
4360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
43615e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // there is a possibility that this is an outstanding message for a
43625e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // codec that we have already destroyed
4363ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    if (mCodec->mNode == 0) {
43645e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar        ALOGI("ignoring message as already freed component: %s",
43655e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar                msg->debugString().c_str());
43665e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar        return true;
43675e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    }
43685e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar
4369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::node_id nodeID;
4370609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("node", (int32_t*)&nodeID));
4371777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (nodeID != mCodec->mNode) {
4372777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("Unexpected message for nodeID: %u, should have been %u", nodeID, mCodec->mNode);
4373777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return false;
4374777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
4375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (type) {
4377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EVENT:
4378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t event, data1, data2;
4380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("event", &event));
4381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data1", &data1));
4382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data2", &data2));
4383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
43840af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            if (event == OMX_EventCmdComplete
43850af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data1 == OMX_CommandFlush
43860af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data2 == (int32_t)OMX_ALL) {
43870af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // Use of this notification is not consistent across
43880af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // implementations. We'll drop this notification and rely
43890af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // on flush-complete notifications on the individual port
43900af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // indices instead.
43910af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
43920af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                return true;
43930af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            }
43940af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
4395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEvent(
4396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_EVENTTYPE>(event),
4397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data1),
4398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data2));
4399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EMPTY_BUFFER_DONE:
4402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
4404609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
4405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEmptyBufferDone(bufferID);
4407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::FILL_BUFFER_DONE:
4410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
4412609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
4413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t rangeOffset, rangeLength, flags;
4415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs;
4416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_offset", &rangeOffset));
4418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_length", &rangeLength));
4419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("flags", &flags));
4420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt64("timestamp", &timeUs));
4421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXFillBufferDone(
4423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    bufferID,
4424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (size_t)rangeOffset, (size_t)rangeLength,
4425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (OMX_U32)flags,
4426784e24e386b088c05d653ab482f2e95cb53e3d01Andy Hung                    timeUs);
4427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4430777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("Unexpected message type: %d", type);
4431777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return false;
4432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4435f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEvent(
4436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (event != OMX_EventError) {
4438ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        ALOGV("[%s] EVENT(%d, 0x%08x, 0x%08x)",
4439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mCodec->mComponentName.c_str(), event, data1, data2);
4440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return false;
4442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4444ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGE("[%s] ERROR(0x%08x)", mCodec->mComponentName.c_str(), data1);
4445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4446251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // verify OMX component sends back an error we expect.
4447251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    OMX_ERRORTYPE omxError = (OMX_ERRORTYPE)data1;
4448251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (!isOMXError(omxError)) {
4449251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        ALOGW("Invalid OMX error %#x", omxError);
4450251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        omxError = OMX_ErrorUndefined;
4451251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
4452251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    mCodec->signalError(omxError);
4453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4457f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID) {
4458ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGV("[%s] onOMXEmptyBufferDone %u",
4459349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber         mCodec->mComponentName.c_str(), bufferID);
4460349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
44610806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
44620806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
44630806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (status != BufferInfo::OWNED_BY_COMPONENT) {
44640806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGE("Wrong ownership in EBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
44650806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->dumpBuffers(kPortIndexInput);
44660806340688c937e7b78c2d89db3809274130df4eLajos Molnar        return false;
44670806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
4468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
4469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
447096e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // We're in "store-metadata-in-buffers" mode, the underlying
447196e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // OMX component had access to data that's implicitly refcounted
447296e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // by this "MediaBuffer" object. Now that the OMX component has
447396e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // told us that it's done with the input buffer, we can decrement
447496e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // the mediaBuffer's reference count.
447596e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    info->mData->setMediaBufferBase(NULL);
4476d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
4478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            postFillThisBuffer(info);
4485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4487777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        case FREE_BUFFERS:
4488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4489777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("SHOULD NOT REACH HERE: cannot free empty output buffers");
4490777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return false;
4491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4496f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
4497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
4498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
4499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
4502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
4504d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatFillThisBuffer);
4505609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    notify->setInt32("buffer-id", info->mBufferID);
4506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mData->meta()->clear();
45082d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    notify->setBuffer("buffer", info->mData);
4509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
45101d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec);
4511609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    reply->setInt32("buffer-id", info->mBufferID);
4512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setMessage("reply", reply);
4514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->post();
4516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
4518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4520f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
4521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
4522609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
45232d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    sp<ABuffer> buffer;
4524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t err = OK;
45255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool eos = false;
4526a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar    PortMode mode = getPortMode(kPortIndexInput);
45275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
45282d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    if (!msg->findBuffer("buffer", &buffer)) {
4529a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar        /* these are unfilled buffers returned by client */
4530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findInt32("err", &err));
4531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
45327fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        if (err == OK) {
45337fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            /* buffers with no errors are returned on MediaCodec.flush */
45347fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            mode = KEEP_BUFFERS;
45357fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        } else {
45367fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            ALOGV("[%s] saw error %d instead of an input buffer",
45377fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                 mCodec->mComponentName.c_str(), err);
45387fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            eos = true;
45397fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        }
45403831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
45412d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber        buffer.clear();
4542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
45445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
45455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
45465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
45475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = ERROR_END_OF_STREAM;
45485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
45495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
45510806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
45520806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (status != BufferInfo::OWNED_BY_UPSTREAM) {
45530806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGE("Wrong ownership in IBF: %s(%d) buffer #%u", _asString(status), status, bufferID);
45540806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->dumpBuffers(kPortIndexInput);
45550806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
45560806340688c937e7b78c2d89db3809274130df4eLajos Molnar        return;
45570806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
4558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
4560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
45645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (eos) {
4565dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (!mCodec->mPortEOS[kPortIndexInput]) {
4566dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
4567dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mInputEOSResult = err;
4568dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
4569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
45755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
4576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int64_t timeUs;
4577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
4578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
4580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t isCSD;
4582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
4583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
4584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
4585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
45865778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (eos) {
45875778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    flags |= OMX_BUFFERFLAG_EOS;
45885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
45895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer != info->mData) {
4591ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] Needs to copy input data for buffer %u. (%p != %p)",
4592d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(),
4593d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         bufferID,
4594d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         buffer.get(), info->mData.get());
4595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
45960806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    if (buffer->size() > info->mData->capacity()) {
45970806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        ALOGE("data size (%zu) is greated than buffer capacity (%zu)",
45980806340688c937e7b78c2d89db3809274130df4eLajos Molnar                                buffer->size(),           // this is the data received
45990806340688c937e7b78c2d89db3809274130df4eLajos Molnar                                info->mData->capacity()); // this is out buffer size
46000806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
46010806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        return;
46020806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    }
4603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    memcpy(info->mData->data(), buffer->data(), buffer->size());
4604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
4605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4606078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
4607ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] calling emptyBuffer %u w/ codec specific data",
4608078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID);
46095778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else if (flags & OMX_BUFFERFLAG_EOS) {
4610ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] calling emptyBuffer %u w/ EOS",
46115778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str(), bufferID);
4612078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                } else {
4613d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
4614ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGI("[%s] calling emptyBuffer %u w/ time %lld us",
4615ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                         mCodec->mComponentName.c_str(), bufferID, (long long)timeUs);
4616d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#else
4617ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] calling emptyBuffer %u w/ time %lld us",
4618ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                         mCodec->mComponentName.c_str(), bufferID, (long long)timeUs);
4619d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
4620078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                }
4621349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4622d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
4623d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ACodec::BufferStats stats;
4624d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
4625d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mFillBufferDoneTimeUs = -1ll;
4626d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mCodec->mBufferStats.add(timeUs, stats);
4627d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
4628d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4629054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                if (mCodec->mStoreMetaDataInOutputBuffers) {
4630054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    // try to submit an output buffer for each input buffer
4631054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    PortMode outputMode = getPortMode(kPortIndexOutput);
4632054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4633054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    ALOGV("MetaDataBuffersToSubmit=%u portMode=%s",
4634054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            mCodec->mMetaDataBuffersToSubmit,
4635054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            (outputMode == FREE_BUFFERS ? "FREE" :
4636054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                             outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
4637054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    if (outputMode == RESUBMIT_BUFFERS) {
4638e53350373ac516257b4f8956ff1e3f1ac48f607eLajos Molnar                        mCodec->submitOutputMetaDataBuffer();
4639054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    }
4640054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                }
46410806340688c937e7b78c2d89db3809274130df4eLajos Molnar                status_t err2 = mCodec->mOMX->emptyBuffer(
46420806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->mNode,
46430806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    bufferID,
46440806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    0,
46450806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    buffer->size(),
46460806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    flags,
46470806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    timeUs);
46480806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err2 != OK) {
46490806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err2));
46500806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    return;
46510806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
4652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
46540806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (!eos && err == OK) {
46555778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    getMoreInputDataIfPossible();
46565778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
46570806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGV("[%s] Signalled EOS (%d) on the input port",
46580806340688c937e7b78c2d89db3809274130df4eLajos Molnar                         mCodec->mComponentName.c_str(), err);
46595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
46605778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
46615778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mInputEOSResult = err;
46625778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
4663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
46640806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err != OK && err != ERROR_END_OF_STREAM) {
46650806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGV("[%s] Signalling EOS on the input port due to error %d",
4666dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str(), err);
4667dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                } else {
46683856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port",
4669dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str());
4670dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
4671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4672ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                ALOGV("[%s] calling emptyBuffer %u signalling EOS",
4673349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                     mCodec->mComponentName.c_str(), bufferID);
4674349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
46750806340688c937e7b78c2d89db3809274130df4eLajos Molnar                status_t err2 = mCodec->mOMX->emptyBuffer(
46760806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        mCodec->mNode,
46770806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        bufferID,
46780806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        0,
46790806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        0,
46800806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        OMX_BUFFERFLAG_EOS,
46810806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        0);
46820806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err2 != OK) {
46830806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err2));
46840806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    return;
46850806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
4686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexInput] = true;
4689dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                mCodec->mInputEOSResult = err;
4690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4693625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih
4694777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        case FREE_BUFFERS:
4695777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            break;
4696777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim
4697625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih        default:
4698777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("invalid port mode: %d", mode);
4699625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih            break;
4700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4703f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::getMoreInputDataIfPossible() {
4704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
4705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
4706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *eligible = NULL;
4709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
4711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
4712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
4714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
4715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // There's already a "read" pending.
4716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
4717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
4719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_US) {
4721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            eligible = info;
4722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (eligible == NULL) {
4726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
4727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(eligible);
4730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4732f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXFillBufferDone(
4733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferID,
4734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        size_t rangeOffset, size_t rangeLength,
4735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 flags,
4736784e24e386b088c05d653ab482f2e95cb53e3d01Andy Hung        int64_t timeUs) {
4737609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] onOMXFillBufferDone %u time %" PRId64 " us, flags = 0x%08x",
47385778822d86b0337407514b9372562b86edfa91cdAndreas Huber         mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
4739349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
47410806340688c937e7b78c2d89db3809274130df4eLajos Molnar    status_t err= OK;
4742d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4743d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
4744d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    index = mCodec->mBufferStats.indexOfKey(timeUs);
4745d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (index >= 0) {
4746d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
4747d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
4748d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4749d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ALOGI("frame PTS %lld: %lld",
4750d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                timeUs,
4751d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
4752d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4753d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mCodec->mBufferStats.removeItemsAt(index);
4754d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats = NULL;
4755d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
4756d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
4757d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
4759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
47600806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
47610806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (status != BufferInfo::OWNED_BY_COMPONENT) {
47620806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGE("Wrong ownership in FBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
47630806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->dumpBuffers(kPortIndexOutput);
47640806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
47650806340688c937e7b78c2d89db3809274130df4eLajos Molnar        return true;
47660806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
4767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4768054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mDequeuedAt = ++mCodec->mDequeueCounter;
4769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
4770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
4772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4775f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4779a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            if (rangeLength == 0 && (!(flags & OMX_BUFFERFLAG_EOS)
4780a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                    || mCodec->mPortEOS[kPortIndexOutput])) {
4781609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                ALOGV("[%s] calling fillBuffer %u",
47825778822d86b0337407514b9372562b86edfa91cdAndreas Huber                     mCodec->mComponentName.c_str(), info->mBufferID);
4783349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
47840806340688c937e7b78c2d89db3809274130df4eLajos Molnar                err = mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID);
47850806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err != OK) {
47860806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
47870806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    return true;
47880806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
4789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
47905778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
47915778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
47925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
479331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4794577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            sp<AMessage> reply =
47951d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar                new AMessage(kWhatOutputBufferDrained, mCodec);
4796577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
47974bdda35319d5f46efea2089b865c8a64816389cdMarco Nelissen            if (!mCodec->mSentFormat && rangeLength > 0) {
4798577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->sendFormatChange(reply);
47995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
4800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4801308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            if (mCodec->mUseMetadataOnEncoderOutput) {
4802308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                native_handle_t* handle =
4803308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        *(native_handle_t**)(info->mData->data() + 4);
4804308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setPointer("handle", handle);
4805308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeOffset", rangeOffset);
4806308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeLength", rangeLength);
4807308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            } else {
4808308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->setRange(rangeOffset, rangeLength);
4809308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            }
4810496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#if 0
481121ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen            if (mCodec->mNativeWindow == NULL) {
4812496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                if (IsIDR(info->mData)) {
4813496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                    ALOGI("IDR frame");
4814496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                }
48155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
481621ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen#endif
4817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
48188b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            if (mCodec->mSkipCutBuffer != NULL) {
48198b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                mCodec->mSkipCutBuffer->submit(info->mData);
48208b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            }
48215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mData->meta()->setInt64("timeUs", timeUs);
4822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
48235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4824d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatDrainThisBuffer);
4825609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            notify->setInt32("buffer-id", info->mBufferID);
48262d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            notify->setBuffer("buffer", info->mData);
48275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("flags", flags);
4828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4829609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            reply->setInt32("buffer-id", info->mBufferID);
4830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
48315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setMessage("reply", reply);
4832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
48335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->post();
48345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
48355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
4836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (flags & OMX_BUFFERFLAG_EOS) {
48385778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
48395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4840f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                sp<AMessage> notify = mCodec->mNotify->dup();
4841d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar                notify->setInt32("what", CodecBase::kWhatEOS);
4842dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                notify->setInt32("err", mCodec->mInputEOSResult);
4843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->post();
4844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexOutput] = true;
4846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4850777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        case FREE_BUFFERS:
48510806340688c937e7b78c2d89db3809274130df4eLajos Molnar            err = mCodec->freeBuffer(kPortIndexOutput, index);
48520806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
48530806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
48540806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
48550806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
4856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4857777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim
4858777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        default:
4859777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("Invalid port mode: %d", mode);
4860777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return false;
4861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4866f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
4867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
4868609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
4869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
48700806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo *info = mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
48710806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
48720806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (status != BufferInfo::OWNED_BY_DOWNSTREAM) {
48730806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGE("Wrong ownership in OBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
48740806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->dumpBuffers(kPortIndexOutput);
48750806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
48760806340688c937e7b78c2d89db3809274130df4eLajos Molnar        return;
48770806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
4878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4879577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    android_native_rect_t crop;
4880777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (msg->findRect("crop", &crop.left, &crop.top, &crop.right, &crop.bottom)) {
4881777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        status_t err = native_window_set_crop(mCodec->mNativeWindow.get(), &crop);
4882777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGW_IF(err != NO_ERROR, "failed to set crop: %d", err);
4883577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    }
4884577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
4885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t render;
4886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mNativeWindow != NULL
48876aade6058521b0dbd35a9a4620f4d04f02f90444Marco Nelissen            && msg->findInt32("render", &render) && render != 0
488879ee2399b67c7a11042c5904dc1309712a76f8cbJianzheng Zhou            && info->mData != NULL && info->mData->size() != 0) {
48896fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        ATRACE_NAME("render");
4890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The client wants this buffer to be rendered.
4891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4892fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        int64_t timestampNs = 0;
4893fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        if (!msg->findInt64("timestampNs", &timestampNs)) {
4894fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // TODO: it seems like we should use the timestamp
4895fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // in the (media)buffer as it potentially came from
4896fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // an input surface, but we did not propagate it prior to
4897fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // API 20.  Perhaps check for target SDK version.
4898fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#if 0
4899fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            if (info->mData->meta()->findInt64("timeUs", &timestampNs)) {
490047aea1f7c58f5302b16822f9e7e1763f2af04ef5Lajos Molnar                ALOGV("using buffer PTS of %" PRId64, timestampNs);
4901fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar                timestampNs *= 1000;
4902fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            }
4903fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#endif
4904fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
4905fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
49065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err;
4907fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        err = native_window_set_buffers_timestamp(mCodec->mNativeWindow.get(), timestampNs);
49080806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGW_IF(err != NO_ERROR, "failed to set buffer timestamp: %d", err);
4909fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
49100806340688c937e7b78c2d89db3809274130df4eLajos Molnar        err = mCodec->mNativeWindow->queueBuffer(
49110806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->mNativeWindow.get(), info->mGraphicBuffer.get(), -1);
49120806340688c937e7b78c2d89db3809274130df4eLajos Molnar        if (err == OK) {
4913cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
4914cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        } else {
4915251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
4916cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
4917cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        }
4918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
49196fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        if (mCodec->mNativeWindow != NULL &&
49206fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar            (info->mData == NULL || info->mData->size() != 0)) {
49216fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar            ATRACE_NAME("frame-drop");
49226fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        }
4923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_US;
4924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
4927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
4932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // We cannot resubmit the buffer we just rendered, dequeue
4935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // the spare instead.
4936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info = mCodec->dequeueBufferFromNativeWindow();
4938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (!mCodec->mPortEOS[kPortIndexOutput]) {
4945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // We cannot resubmit the buffer we just rendered, dequeue
4947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // the spare instead.
4948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info = mCodec->dequeueBufferFromNativeWindow();
4950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
4951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4952c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                if (info != NULL) {
4953609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                    ALOGV("[%s] calling fillBuffer %u",
4954c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                         mCodec->mComponentName.c_str(), info->mBufferID);
49550806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    status_t err = mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID);
49560806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    if (err == OK) {
49570806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
49580806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    } else {
49590806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
49600806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    }
4961c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                }
4962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4966777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        case FREE_BUFFERS:
4967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
49680806340688c937e7b78c2d89db3809274130df4eLajos Molnar            status_t err = mCodec->freeBuffer(kPortIndexOutput, index);
49690806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
49700806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
49710806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
4972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4974777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim
4975777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        default:
4976777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("Invalid port mode: %d", mode);
4977777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return;
4978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4983f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::UninitializedState::UninitializedState(ACodec *codec)
4984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4987c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::UninitializedState::stateEntered() {
4988c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("Now uninitialized");
4989ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4990ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (mDeathNotifier != NULL) {
4991f888020c6e2735624f2b2a30e72aca24e17b8b4dMarco Nelissen        IInterface::asBinder(mCodec->mOMX)->unlinkToDeath(mDeathNotifier);
4992ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
4993ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
4994ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4995ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNativeWindow.clear();
4996ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    mCodec->mNode = 0;
4997ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mOMX.clear();
4998ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mQuirks = 0;
4999ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mFlags = 0;
5000308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    mCodec->mUseMetadataOnEncoderOutput = 0;
5001ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mComponentName.clear();
5002c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
5003c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5004f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
5005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatSetup:
5009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onSetup(msg);
5011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
50165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case ACodec::kWhatAllocateComponent:
50175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
50185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            onAllocateComponent(msg);
50195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            handled = true;
50205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
50215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
50225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatShutdown:
5024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5025c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
5026c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
5027c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
502854b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            ALOGW_IF(keepComponentAllocated,
502954b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar                     "cannot keep component allocated on shutdown in Uninitialized state");
5030c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
5032d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
5033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
5034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5036c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
5037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatFlush:
5040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
5042d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
5043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
5044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5046c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
5047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
504930358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        case ACodec::kWhatReleaseCodecInstance:
505030358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        {
505130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            // nothing to do, as we have already signaled shutdown
505230358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            handled = true;
505330358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            break;
505430358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        }
505530358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar
5056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
5058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5063f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::UninitializedState::onSetup(
5064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
5065c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (onAllocateComponent(msg)
5066c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            && mCodec->mLoadedState->onConfigureComponent(msg)) {
5067c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mLoadedState->onStart();
5068c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
50695778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
50705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5071c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
50725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onAllocateComponent");
50735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5074ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    CHECK(mCodec->mNode == 0);
50755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMXClient client;
507748a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung    if (client.connect() != OK) {
507848a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung        mCodec->signalError(OMX_ErrorUndefined, NO_INIT);
507948a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung        return false;
508048a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung    }
5081f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<IOMX> omx = client.interface();
5083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
50841d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec);
5085ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
5086ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mDeathNotifier = new DeathNotifier(notify);
5087f888020c6e2735624f2b2a30e72aca24e17b8b4dMarco Nelissen    if (IInterface::asBinder(omx)->linkToDeath(mDeathNotifier) != OK) {
5088ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // This was a local binder, if it dies so do we, we won't care
5089ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // about any notifications in the afterlife.
5090ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
5091ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
5092ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
5093e671207115fac3914134c61b336d5fa0242c68caAndreas Huber    Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs;
50945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5095f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    AString mime;
5096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
50975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString componentName;
5098d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint32_t quirks = 0;
50997791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen    int32_t encoder = false;
51005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findString("componentName", &componentName)) {
5101e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        ssize_t index = matchingCodecs.add();
5102e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        OMXCodec::CodecNameAndQuirks *entry = &matchingCodecs.editItemAt(index);
5103e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        entry->mName = String8(componentName.c_str());
5104afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
5105e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        if (!OMXCodec::findCodecQuirks(
5106e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                    componentName.c_str(), &entry->mQuirks)) {
5107e671207115fac3914134c61b336d5fa0242c68caAndreas Huber            entry->mQuirks = 0;
5108afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
51095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
51105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(msg->findString("mime", &mime));
51115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
51125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("encoder", &encoder)) {
51135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder = false;
51145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
51155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
51165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMXCodec::findMatchingCodecs(
51175778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mime.c_str(),
51185778822d86b0337407514b9372562b86edfa91cdAndreas Huber                encoder, // createEncoder
51195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                NULL,  // matchComponentName
51205778822d86b0337407514b9372562b86edfa91cdAndreas Huber                0,     // flags
5121e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                &matchingCodecs);
51225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
51231065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
51241065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    sp<CodecObserver> observer = new CodecObserver;
5125ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    IOMX::node_id node = 0;
51261065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
51279f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu    status_t err = OMX_ErrorComponentNotFound;
51281065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
51291065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            ++matchIndex) {
5130e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        componentName = matchingCodecs.itemAt(matchIndex).mName.string();
5131e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        quirks = matchingCodecs.itemAt(matchIndex).mQuirks;
5132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5133da153975581fb3161a30452348a5b26ee72d9255Elliott Hughes        pid_t tid = gettid();
5134078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        int prevPriority = androidGetThreadPriority(tid);
5135078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
51369f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu        err = omx->allocateNode(componentName.c_str(), observer, &node);
5137078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, prevPriority);
5138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
51391065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        if (err == OK) {
51401065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            break;
51417a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He        } else {
51427a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He            ALOGW("Allocating component '%s' failed, try next one.", componentName.c_str());
51431065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
51441065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
5145ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        node = 0;
51461065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    }
51471065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
5148ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    if (node == 0) {
51495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!mime.empty()) {
51509f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu            ALOGE("Unable to instantiate a %scoder for type '%s' with err %#x.",
51519f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu                    encoder ? "en" : "de", mime.c_str(), err);
51525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
51539f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu            ALOGE("Unable to instantiate codec '%s' with err %#x.", componentName.c_str(), err);
51545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
5155c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
515652e88b2986536e83a7a6da63461556b8734a85f3Ronghua Wu        mCodec->signalError((OMX_ERRORTYPE)err, makeNoSideEffectStatus(err));
5157c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
5158c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
5159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
51601d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    notify = new AMessage(kWhatOMXMessage, mCodec);
5161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    observer->setNotificationMessage(notify);
5162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mComponentName = componentName;
5164ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    mCodec->mFlags = 0;
5165ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
5166ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (componentName.endsWith(".secure")) {
5167ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        mCodec->mFlags |= kFlagIsSecure;
51681713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        mCodec->mFlags |= kFlagIsGrallocUsageProtected;
51690167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
5170ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
5171ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
5172afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mCodec->mQuirks = quirks;
5173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mOMX = omx;
5174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mNode = node;
5175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
51765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
51775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
5178d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatComponentAllocated);
51795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setString("componentName", mCodec->mComponentName.c_str());
51805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
51815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5182c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5183c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mCodec->changeState(mCodec->mLoadedState);
5184c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5185c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
51865778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
51875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5188c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
5189c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5190c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas HuberACodec::LoadedState::LoadedState(ACodec *codec)
5191c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    : BaseState(codec) {
5192c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
5193c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5194c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::stateEntered() {
5195c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
5196c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5197f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mPortEOS[kPortIndexInput] =
5198f6f38287b97ec69b169387add6458f859b770e65Andreas Huber        mCodec->mPortEOS[kPortIndexOutput] = false;
5199f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
5200f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mInputEOSResult = OK;
5201f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
5202054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mDequeueCounter = 0;
5203054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mMetaDataBuffersToSubmit = 0;
5204a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    mCodec->mRepeatFrameDelayUs = -1ll;
5205e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mInputFormat.clear();
5206e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mOutputFormat.clear();
52074e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    mCodec->mBaseOutputFormat.clear();
5208054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5209c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (mCodec->mShutdownInProgress) {
5210c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
5211c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5212c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mShutdownInProgress = false;
5213c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mKeepComponentAllocated = false;
5214c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5215c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        onShutdown(keepComponentAllocated);
5216c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
521754b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    mCodec->mExplicitShutdown = false;
5218f393c33e65ae51a7cf168b4e15771b152f996b32Wei Jia
5219f393c33e65ae51a7cf168b4e15771b152f996b32Wei Jia    mCodec->processDeferredMessages();
5220c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
5221c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5222c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
5223c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (!keepComponentAllocated) {
52240806340688c937e7b78c2d89db3809274130df4eLajos Molnar        (void)mCodec->mOMX->freeNode(mCodec->mNode);
5225c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5226c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->changeState(mCodec->mUninitializedState);
5227c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
5228c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
522954b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    if (mCodec->mExplicitShutdown) {
523054b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        sp<AMessage> notify = mCodec->mNotify->dup();
5231d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
523254b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        notify->post();
523354b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        mCodec->mExplicitShutdown = false;
523454b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    }
5235c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
5236c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5237c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
5238c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool handled = false;
5239c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5240c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    switch (msg->what()) {
5241c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatConfigureComponent:
5242c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
5243c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onConfigureComponent(msg);
5244c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
5245c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
5246c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
5247c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
52487cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
52497cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
52507cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            onCreateInputSurface(msg);
52517cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
52527cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
52537cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
52547cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
5255d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        case ACodec::kWhatUsePersistentInputSurface:
5256d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        {
5257d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            onUsePersistentInputSurface(msg);
5258d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            handled = true;
5259d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            break;
5260d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        }
5261d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5262c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatStart:
5263c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
5264c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onStart();
5265c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
5266c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
5267c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
5268c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5269c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatShutdown:
5270c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
5271c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
5272c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
5273c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
5274c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
527554b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
5276c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onShutdown(keepComponentAllocated);
5277c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5278c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
5279c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
5280c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
5281c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5282c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatFlush:
5283c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
5284c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
5285d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
5286c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->post();
5287c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5288c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
5289c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
5290c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
5291c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5292c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        default:
5293c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            return BaseState::onMessageReceived(msg);
5294c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
5295c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5296c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return handled;
5297c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
5298c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5299c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onConfigureComponent(
53005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg) {
53015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onConfigureComponent");
53025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5303ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    CHECK(mCodec->mNode != 0);
53045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
53050806340688c937e7b78c2d89db3809274130df4eLajos Molnar    status_t err = OK;
53065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString mime;
53070806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (!msg->findString("mime", &mime)) {
53080806340688c937e7b78c2d89db3809274130df4eLajos Molnar        err = BAD_VALUE;
53090806340688c937e7b78c2d89db3809274130df4eLajos Molnar    } else {
53100806340688c937e7b78c2d89db3809274130df4eLajos Molnar        err = mCodec->configureCodec(mime.c_str(), msg);
53110806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
53125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
5313c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        ALOGE("[%s] configureCodec returning error %d",
5314c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber              mCodec->mComponentName.c_str(), err);
5315c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber
5316251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5317c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
53185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
53205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
53215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
5322d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatComponentConfigured);
5323e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("input-format", mCodec->mInputFormat);
5324e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("output-format", mCodec->mOutputFormat);
53255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
53265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5327c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5328c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
53295778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
53305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5331d291c222357303b9611cab89d0c3b047584ef377Chong Zhangstatus_t ACodec::LoadedState::setupInputSurface() {
5332d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    status_t err = OK;
5333a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
5334d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mRepeatFrameDelayUs > 0ll) {
5335a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        err = mCodec->mOMX->setInternalOption(
5336a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                mCodec->mNode,
5337a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                kPortIndexInput,
5338a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY,
5339a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                &mCodec->mRepeatFrameDelayUs,
5340a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                sizeof(mCodec->mRepeatFrameDelayUs));
5341a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
5342a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (err != OK) {
5343a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            ALOGE("[%s] Unable to configure option to repeat previous "
5344a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  "frames (err %d)",
5345a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  mCodec->mComponentName.c_str(),
5346a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  err);
5347d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
5348a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
5349a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
5350a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
5351d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mMaxPtsGapUs > 0ll) {
535294ee4b708acfa941581160b267afb79192b1d816Chong Zhang        err = mCodec->mOMX->setInternalOption(
535394ee4b708acfa941581160b267afb79192b1d816Chong Zhang                mCodec->mNode,
535494ee4b708acfa941581160b267afb79192b1d816Chong Zhang                kPortIndexInput,
535594ee4b708acfa941581160b267afb79192b1d816Chong Zhang                IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP,
535694ee4b708acfa941581160b267afb79192b1d816Chong Zhang                &mCodec->mMaxPtsGapUs,
535794ee4b708acfa941581160b267afb79192b1d816Chong Zhang                sizeof(mCodec->mMaxPtsGapUs));
535894ee4b708acfa941581160b267afb79192b1d816Chong Zhang
535994ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (err != OK) {
536094ee4b708acfa941581160b267afb79192b1d816Chong Zhang            ALOGE("[%s] Unable to configure max timestamp gap (err %d)",
536172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    mCodec->mComponentName.c_str(),
536272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    err);
5363d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
53642c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
53652c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
53662c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
5367d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mMaxFps > 0) {
536837b2b389139ed638831e49708c947863eef631efRonghua Wu        err = mCodec->mOMX->setInternalOption(
536937b2b389139ed638831e49708c947863eef631efRonghua Wu                mCodec->mNode,
537037b2b389139ed638831e49708c947863eef631efRonghua Wu                kPortIndexInput,
537137b2b389139ed638831e49708c947863eef631efRonghua Wu                IOMX::INTERNAL_OPTION_MAX_FPS,
537237b2b389139ed638831e49708c947863eef631efRonghua Wu                &mCodec->mMaxFps,
537337b2b389139ed638831e49708c947863eef631efRonghua Wu                sizeof(mCodec->mMaxFps));
537437b2b389139ed638831e49708c947863eef631efRonghua Wu
537537b2b389139ed638831e49708c947863eef631efRonghua Wu        if (err != OK) {
537637b2b389139ed638831e49708c947863eef631efRonghua Wu            ALOGE("[%s] Unable to configure max fps (err %d)",
537737b2b389139ed638831e49708c947863eef631efRonghua Wu                    mCodec->mComponentName.c_str(),
537837b2b389139ed638831e49708c947863eef631efRonghua Wu                    err);
5379d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
538037b2b389139ed638831e49708c947863eef631efRonghua Wu        }
538137b2b389139ed638831e49708c947863eef631efRonghua Wu    }
538237b2b389139ed638831e49708c947863eef631efRonghua Wu
5383d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mTimePerCaptureUs > 0ll
53842c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            && mCodec->mTimePerFrameUs > 0ll) {
53852c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        int64_t timeLapse[2];
53862c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[0] = mCodec->mTimePerFrameUs;
53872c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[1] = mCodec->mTimePerCaptureUs;
53882c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        err = mCodec->mOMX->setInternalOption(
53892c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                mCodec->mNode,
53902c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                kPortIndexInput,
53912c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                IOMX::INTERNAL_OPTION_TIME_LAPSE,
53922c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                &timeLapse[0],
53932c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                sizeof(timeLapse));
53942c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
53952c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (err != OK) {
53962c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            ALOGE("[%s] Unable to configure time lapse (err %d)",
53972c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    mCodec->mComponentName.c_str(),
53982c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    err);
5399d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
54002c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
54012c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
540272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
5403d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mCreateInputBuffersSuspended) {
540472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        bool suspend = true;
540572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        err = mCodec->mOMX->setInternalOption(
540672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                mCodec->mNode,
540772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                kPortIndexInput,
540872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                IOMX::INTERNAL_OPTION_SUSPEND,
540972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                &suspend,
541072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                sizeof(suspend));
541172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
541272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
541372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("[%s] Unable to configure option to suspend (err %d)",
541494ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  mCodec->mComponentName.c_str(),
541594ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  err);
5416d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
541794ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
541894ee4b708acfa941581160b267afb79192b1d816Chong Zhang    }
541994ee4b708acfa941581160b267afb79192b1d816Chong Zhang
5420d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    return OK;
5421d291c222357303b9611cab89d0c3b047584ef377Chong Zhang}
5422d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5423d291c222357303b9611cab89d0c3b047584ef377Chong Zhangvoid ACodec::LoadedState::onCreateInputSurface(
5424d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        const sp<AMessage> & /* msg */) {
5425d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    ALOGV("onCreateInputSurface");
5426d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5427d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<AMessage> notify = mCodec->mNotify->dup();
5428d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    notify->setInt32("what", CodecBase::kWhatInputSurfaceCreated);
5429d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5430d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<IGraphicBufferProducer> bufferProducer;
5431d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    status_t err = mCodec->mOMX->createInputSurface(
5432d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            mCodec->mNode, kPortIndexInput, &bufferProducer);
5433d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5434d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (err == OK) {
5435d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        err = setupInputSurface();
5436d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    }
5437d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
54387cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err == OK) {
54397cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setObject("input-surface",
54407cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                new BufferProducerWrapper(bufferProducer));
54417cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else {
54427cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // Can't use mCodec->signalError() here -- MediaCodec won't forward
54437cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // the error through because it's in the "configured" state.  We
54447cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // send a kWhatInputSurfaceCreated with an error value instead.
54457cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGE("[%s] onCreateInputSurface returning error %d",
54467cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                mCodec->mComponentName.c_str(), err);
54477cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setInt32("err", err);
54487cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
54497cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->post();
54507cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
54517cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
5452d291c222357303b9611cab89d0c3b047584ef377Chong Zhangvoid ACodec::LoadedState::onUsePersistentInputSurface(
5453d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        const sp<AMessage> &msg) {
5454d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    ALOGV("onUsePersistentInputSurface");
5455d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5456d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<AMessage> notify = mCodec->mNotify->dup();
5457d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    notify->setInt32("what", CodecBase::kWhatInputSurfaceAccepted);
5458d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5459d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<RefBase> obj;
5460d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    CHECK(msg->findObject("input-surface", &obj));
5461d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<PersistentSurface> surface = static_cast<PersistentSurface *>(obj.get());
5462d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5463d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    status_t err = mCodec->mOMX->usePersistentInputSurface(
5464d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            mCodec->mNode, kPortIndexInput, surface->getBufferConsumer());
5465d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5466d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (err == OK) {
5467d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        err = setupInputSurface();
5468d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    }
5469d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5470d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (err != OK) {
5471d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        // Can't use mCodec->signalError() here -- MediaCodec won't forward
5472d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        // the error through because it's in the "configured" state.  We
5473d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        // send a kWhatInputSurfaceAccepted with an error value instead.
5474d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        ALOGE("[%s] onUsePersistentInputSurface returning error %d",
5475d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                mCodec->mComponentName.c_str(), err);
5476d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        notify->setInt32("err", err);
5477d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    }
5478d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    notify->post();
5479d291c222357303b9611cab89d0c3b047584ef377Chong Zhang}
5480d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5481c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onStart() {
54825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onStart");
54835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
54840806340688c937e7b78c2d89db3809274130df4eLajos Molnar    status_t err = mCodec->mOMX->sendCommand(mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle);
54850806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (err != OK) {
54860806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
54870806340688c937e7b78c2d89db3809274130df4eLajos Molnar    } else {
54880806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->changeState(mCodec->mLoadedToIdleState);
54890806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
5490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5494f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
5495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5498f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::LoadedToIdleState::stateEntered() {
54993856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
5500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5501cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    status_t err;
5502cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    if ((err = allocateBuffers()) != OK) {
550329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to allocate buffers after transitioning to IDLE state "
5504cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             "(error 0x%08x)",
5505cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             err);
5506cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
5507251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
550891bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber
550991bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber        mCodec->changeState(mCodec->mLoadedState);
5510cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    }
5511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5513f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::LoadedToIdleState::allocateBuffers() {
5514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
5515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
5517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
5518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mCodec->allocateBuffersOnPort(kPortIndexOutput);
5521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5523f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
5524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
552572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
5526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
5529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
55326507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
55336507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
55346507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
55356507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
55366507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
55376507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
55386463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatResume:
55396463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
55406463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We'll be active soon enough.
55416463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
55426463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
55436463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
55446463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatFlush:
55456463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
55466463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We haven't even started yet, so we're flushed alright...
55476463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            sp<AMessage> notify = mCodec->mNotify->dup();
5548d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
55496463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->post();
55506463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
55516463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
55526463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
5553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
5555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5558f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onOMXEvent(
5559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
55630806340688c937e7b78c2d89db3809274130df4eLajos Molnar            status_t err = OK;
55640806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandStateSet
55650806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    || data2 != (OMX_U32)OMX_StateIdle) {
55660806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("Unexpected command completion in LoadedToIdleState: %s(%u) %s(%u)",
55670806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1,
55680806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_STATETYPE)data2), data2);
55690806340688c937e7b78c2d89db3809274130df4eLajos Molnar                err = FAILED_TRANSACTION;
55700806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
5571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
55720806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err == OK) {
55730806340688c937e7b78c2d89db3809274130df4eLajos Molnar                err = mCodec->mOMX->sendCommand(
55740806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting);
55750806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
5576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
55770806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
55780806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
55790806340688c937e7b78c2d89db3809274130df4eLajos Molnar            } else {
55800806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->changeState(mCodec->mIdleToExecutingState);
55810806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
5582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5593f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
5594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5597f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToExecutingState::stateEntered() {
55983856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
5599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5601f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
5602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
560372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
5604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
5607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5610d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatResume:
5611d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
5612d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We'll be active soon enough.
5613d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
5614d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
5615d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
5616d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatFlush:
5617d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
5618d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We haven't even started yet, so we're flushed alright...
5619d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
5620d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
5621d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->post();
5622d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
5623d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
5624d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
5625d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
56266507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
56276507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
56286507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
56296507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
56306507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
56316507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
5632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
5634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5637f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onOMXEvent(
5638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
56420806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandStateSet
56430806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    || data2 != (OMX_U32)OMX_StateExecuting) {
56440806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("Unexpected command completion in IdleToExecutingState: %s(%u) %s(%u)",
56450806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1,
56460806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_STATETYPE)data2), data2);
56470806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
56480806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
56490806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
5650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mExecutingState->resume();
5652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingState);
5653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5664f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingState::ExecutingState(ACodec *codec)
5665349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    : BaseState(codec),
5666349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber      mActive(false) {
5667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5669f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
5670ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
5671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
5672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5674054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputMetaBuffers() {
5675054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // submit as many buffers as there are input buffers with the codec
5676054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // in case we are in port reconfiguring
5677054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
5678054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
5679054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5680054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) {
5681054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            if (mCodec->submitOutputMetaDataBuffer() != OK)
5682054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                break;
5683054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
5684054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
56854dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
56864dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
56874dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
5688054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
5689054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5690054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitRegularOutputBuffers() {
56910806340688c937e7b78c2d89db3809274130df4eLajos Molnar    bool failed = false;
5692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
5693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
5694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mCodec->mNativeWindow != NULL) {
56960806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (info->mStatus != BufferInfo::OWNED_BY_US
56970806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
56980806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("buffers should be owned by us or the surface");
56990806340688c937e7b78c2d89db3809274130df4eLajos Molnar                failed = true;
57000806340688c937e7b78c2d89db3809274130df4eLajos Molnar                break;
57010806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
5702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
5704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                continue;
5705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
57070806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (info->mStatus != BufferInfo::OWNED_BY_US) {
57080806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("buffers should be owned by us");
57090806340688c937e7b78c2d89db3809274130df4eLajos Molnar                failed = true;
57100806340688c937e7b78c2d89db3809274130df4eLajos Molnar                break;
57110806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
5712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
57140806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGV("[%s] calling fillBuffer %u", mCodec->mComponentName.c_str(), info->mBufferID);
5715349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
57160806340688c937e7b78c2d89db3809274130df4eLajos Molnar        status_t err = mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID);
57170806340688c937e7b78c2d89db3809274130df4eLajos Molnar        if (err != OK) {
57180806340688c937e7b78c2d89db3809274130df4eLajos Molnar            failed = true;
57190806340688c937e7b78c2d89db3809274130df4eLajos Molnar            break;
57200806340688c937e7b78c2d89db3809274130df4eLajos Molnar        }
5721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
5723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
57240806340688c937e7b78c2d89db3809274130df4eLajos Molnar
57250806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (failed) {
57260806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
57270806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
5728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5730054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputBuffers() {
5731c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar    submitRegularOutputBuffers();
5732054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mCodec->mStoreMetaDataInOutputBuffers) {
5733054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        submitOutputMetaBuffers();
5734054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
5735054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
5736054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5737f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::resume() {
5738349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    if (mActive) {
57390806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGV("[%s] We're already active, no need to resume.", mCodec->mComponentName.c_str());
5740349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        return;
5741349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    }
5742349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    submitOutputBuffers();
5744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
57453cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    // Post all available input buffers
5746777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (mCodec->mBuffers[kPortIndexInput].size() == 0u) {
5747777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGW("[%s] we don't have any input buffers to resume", mCodec->mComponentName.c_str());
5748777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
5749777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim
57503cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); i++) {
57513cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
57523cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_US) {
57533cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar            postFillThisBuffer(info);
57543cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        }
57553cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    }
5756349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5757349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    mActive = true;
5758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5760f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::stateEntered() {
57613856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
5762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->processDeferredMessages();
5764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5766f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
5767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5772c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
5773c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
5774c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
5775c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5776c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mShutdownInProgress = true;
577754b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
5778c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mKeepComponentAllocated = keepComponentAllocated;
5779c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5780349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
5781349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
57820806340688c937e7b78c2d89db3809274130df4eLajos Molnar            status_t err = mCodec->mOMX->sendCommand(
57830806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle);
57840806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
57850806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (keepComponentAllocated) {
57860806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
57870806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
57880806340688c937e7b78c2d89db3809274130df4eLajos Molnar                // TODO: do some recovery here.
57890806340688c937e7b78c2d89db3809274130df4eLajos Molnar            } else {
57900806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->changeState(mCodec->mExecutingToIdleState);
57910806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
5792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
57997a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong            ALOGV("[%s] ExecutingState flushing now "
5800ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                 "(codec owns %zu/%zu input, %zu/%zu output).",
5801d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mComponentName.c_str(),
5802d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
5803d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexInput].size(),
5804d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
5805d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexOutput].size());
5806d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
5807349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
5808349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
58090806340688c937e7b78c2d89db3809274130df4eLajos Molnar            status_t err = mCodec->mOMX->sendCommand(mCodec->mNode, OMX_CommandFlush, OMX_ALL);
58100806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
58110806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
58120806340688c937e7b78c2d89db3809274130df4eLajos Molnar            } else {
58130806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->changeState(mCodec->mFlushingState);
58140806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
5815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatResume:
5821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            resume();
5823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5828496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
5829496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
5830496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            status_t err = mCodec->requestIDRFrame();
5831496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            if (err != OK) {
5832496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                ALOGW("Requesting an IDR frame failed.");
5833496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            }
5834496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5835496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            handled = true;
5836496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
5837496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
5838496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5839a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
5840a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
5841a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
5842a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
5843a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5844a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = mCodec->setParameters(params);
5845a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5846a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> reply;
5847a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            if (msg->findMessage("reply", &reply)) {
5848a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->setInt32("err", err);
5849a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->post();
5850a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            }
5851a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5852a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            handled = true;
5853a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
5854a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
5855a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
58567cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
58577cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
58586507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
58597cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
58607cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
58617cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
58627cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
58634dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
58644dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        case kWhatSubmitOutputMetaDataBufferIfEOS:
58654dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        {
58664dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            if (mCodec->mPortEOS[kPortIndexInput] &&
58674dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    !mCodec->mPortEOS[kPortIndexOutput]) {
58684dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                status_t err = mCodec->submitOutputMetaDataBuffer();
58694dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                if (err == OK) {
58704dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
58714dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                }
58724dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            }
58734dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            return true;
58744dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        }
58754dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
5876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5884a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t ACodec::setParameters(const sp<AMessage> &params) {
5885a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    int32_t videoBitrate;
5886530fdbdc1b5491f3fbf172752834d1515701e142Lajos Molnar    if (params->findInt32("video-bitrate", &videoBitrate)) {
5887a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        OMX_VIDEO_CONFIG_BITRATETYPE configParams;
5888a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        InitOMXParams(&configParams);
5889a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nPortIndex = kPortIndexOutput;
5890a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nEncodeBitrate = videoBitrate;
5891a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5892a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        status_t err = mOMX->setConfig(
5893a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                mNode,
5894a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                OMX_IndexConfigVideoBitrate,
5895a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                &configParams,
5896a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                sizeof(configParams));
5897a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5898a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        if (err != OK) {
5899a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
5900a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                   videoBitrate, err);
5901a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5902a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            return err;
5903a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
5904a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    }
5905a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
590672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    int64_t skipFramesBeforeUs;
590772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (params->findInt64("skip-frames-before", &skipFramesBeforeUs)) {
590872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        status_t err =
590972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mOMX->setInternalOption(
591072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     mNode,
591172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     kPortIndexInput,
591272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     IOMX::INTERNAL_OPTION_START_TIME,
591372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     &skipFramesBeforeUs,
591472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     sizeof(skipFramesBeforeUs));
591572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
591672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
591772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("Failed to set parameter 'skip-frames-before' (err %d)", err);
591872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            return err;
591972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
592072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
592172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
5922e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    int32_t dropInputFrames;
5923e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    if (params->findInt32("drop-input-frames", &dropInputFrames)) {
5924e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        bool suspend = dropInputFrames != 0;
5925e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
5926b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err =
5927b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            mOMX->setInternalOption(
5928e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     mNode,
5929e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     kPortIndexInput,
5930e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     IOMX::INTERNAL_OPTION_SUSPEND,
5931e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     &suspend,
5932b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber                     sizeof(suspend));
5933b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
5934b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
5935b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err);
5936b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
5937b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
5938b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    }
5939b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
5940b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    int32_t dummy;
5941b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    if (params->findInt32("request-sync", &dummy)) {
5942b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err = requestIDRFrame();
5943b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
5944b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
5945b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Requesting a sync frame failed w/ err %d", err);
5946b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
5947b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
5948e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    }
5949e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
59508db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    float rate;
59518db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    if (params->findFloat("operating-rate", &rate) && rate > 0) {
59528db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        status_t err = setOperatingRate(rate, mIsVideo);
59538db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        if (err != OK) {
59548db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu            ALOGE("Failed to set parameter 'operating-rate' (err %d)", err);
59558db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu            return err;
59568db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        }
59578db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    }
59588db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu
5959a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return OK;
5960a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
5961a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
59626507d14c6d10f93d390de62b9eed267f9b544985Andy McFaddenvoid ACodec::onSignalEndOfInputStream() {
59636507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    sp<AMessage> notify = mNotify->dup();
5964d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatSignaledInputEOS);
59656507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
59666507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    status_t err = mOMX->signalEndOfInputStream(mNode);
59676507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    if (err != OK) {
59686507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        notify->setInt32("err", err);
59696507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    }
59706507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->post();
59716507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden}
59726507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
5973f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onOMXEvent(
5974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventPortSettingsChanged:
5977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
5979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
598031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
5981054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mCodec->mMetaDataBuffersToSubmit = 0;
5982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
5983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
5984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_CommandPortDisable, kPortIndexOutput),
5985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
5986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5987349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                mCodec->freeOutputBuffersNotOwnedByComponent();
5988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
599031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            } else if (data2 == OMX_IndexConfigCommonOutputCrop) {
599131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
5992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
5993ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08x",
5994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->mComponentName.c_str(), data2);
5995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventBufferFlag:
6001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
6007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
6011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6012f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
6013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ACodec *codec)
6014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
6015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6017f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
6018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
6019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput) {
6020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return FREE_BUFFERS;
6021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
6024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
6026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6028f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onMessageReceived(
6029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
6030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
6031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
6033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
6034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
6035349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case kWhatResume:
6036e6eea3a6b6e0cf92287ec1ceb8350f201d17e1acPer Persson        case kWhatSetParameters:
6037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6038349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            if (msg->what() == kWhatResume) {
60393856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
6040349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            }
6041349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
6043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
6049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
6053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6055f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::OutputPortSettingsChangedState::stateEntered() {
60563856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now handling output port settings change",
6057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mCodec->mComponentName.c_str());
6058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6060f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onOMXEvent(
6061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
6063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
6064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
60660806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (data2 != (OMX_U32)kPortIndexOutput) {
60670806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGW("ignoring EventCmdComplete CommandPortDisable for port %u", data2);
60680806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    return false;
60690806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
6070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
60710806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGV("[%s] Output port now disabled.", mCodec->mComponentName.c_str());
6072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
60730806340688c937e7b78c2d89db3809274130df4eLajos Molnar                status_t err = OK;
60740806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (!mCodec->mBuffers[kPortIndexOutput].isEmpty()) {
60750806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGE("disabled port should be empty, but has %zu buffers",
60760806340688c937e7b78c2d89db3809274130df4eLajos Molnar                            mCodec->mBuffers[kPortIndexOutput].size());
60770806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    err = FAILED_TRANSACTION;
60780806340688c937e7b78c2d89db3809274130df4eLajos Molnar                } else {
60790806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->mDealer[kPortIndexOutput].clear();
60800806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
6081f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
60820806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err == OK) {
60830806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    err = mCodec->mOMX->sendCommand(
60840806340688c937e7b78c2d89db3809274130df4eLajos Molnar                            mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput);
60850806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
6086f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
60870806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err == OK) {
60880806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    err = mCodec->allocateBuffersOnPort(kPortIndexOutput);
60890806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGE_IF(err != OK, "Failed to allocate output port buffers after port "
60900806340688c937e7b78c2d89db3809274130df4eLajos Molnar                            "reconfiguration: (%d)", err);
60910806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
6092cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
60930806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err != OK) {
6094251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
6095d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
6096755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // This is technically not correct, but appears to be
6097755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the only way to free the component instance.
6098755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // Controlled transitioning from excecuting->idle
6099755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // and idle->loaded seem impossible probably because
6100755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the output port never finishes re-enabling.
6101755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mShutdownInProgress = true;
6102755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mKeepComponentAllocated = false;
6103755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->changeState(mCodec->mLoadedState);
6104cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                }
6105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
6107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
6108777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (data2 != (OMX_U32)kPortIndexOutput) {
6109777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGW("ignoring EventCmdComplete OMX_CommandPortEnable for port %u", data2);
6110777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return false;
6111777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
6112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
611331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
611431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
61150806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGV("[%s] Output port now reenabled.", mCodec->mComponentName.c_str());
6116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6117349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                if (mCodec->mExecutingState->active()) {
6118349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    mCodec->mExecutingState->submitOutputBuffers();
6119349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                }
6120349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mExecutingState);
6122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
6124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
6125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
6127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
6131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
6135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6136f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
61375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : BaseState(codec),
61385778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mComponentNowIdle(false) {
6139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6141f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
6142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
6143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
6145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
6146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
6148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
61490806340688c937e7b78c2d89db3809274130df4eLajos Molnar            ALOGW("Ignoring flush request in ExecutingToIdleState");
6150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
6154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
6156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
6163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
6167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6169f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::stateEntered() {
61703856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
617131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
61725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mComponentNowIdle = false;
617331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mCodec->mSentFormat = false;
6174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6176f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onOMXEvent(
6177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
6179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
6180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
61810806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandStateSet
61820806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    || data2 != (OMX_U32)OMX_StateIdle) {
61830806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("Unexpected command completion in ExecutingToIdleState: %s(%u) %s(%u)",
61840806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1,
61850806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_STATETYPE)data2), data2);
61860806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
61870806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
61880806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
61905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mComponentNowIdle = true;
61915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            changeStateIfWeOwnAllBuffers();
6193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6197349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
6198349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventBufferFlag:
6199349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
6200349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We're shutting down and don't care about this anymore.
6201349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
6202349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
6203349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
6206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
62080af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
6209f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
62105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
62110806340688c937e7b78c2d89db3809274130df4eLajos Molnar        status_t err = mCodec->mOMX->sendCommand(
62120806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded);
62130806340688c937e7b78c2d89db3809274130df4eLajos Molnar        if (err == OK) {
62140806340688c937e7b78c2d89db3809274130df4eLajos Molnar            err = mCodec->freeBuffersOnPort(kPortIndexInput);
62150806340688c937e7b78c2d89db3809274130df4eLajos Molnar            status_t err2 = mCodec->freeBuffersOnPort(kPortIndexOutput);
62160806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err == OK) {
62170806340688c937e7b78c2d89db3809274130df4eLajos Molnar                err = err2;
62180806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
62190806340688c937e7b78c2d89db3809274130df4eLajos Molnar        }
6220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
62210167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown)
62220167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && mCodec->mNativeWindow != NULL) {
6223bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // We push enough 1x1 blank buffers to ensure that one of
6224bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // them has made it to the display.  This allows the OMX
6225bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // component teardown to zero out any protected buffers
6226bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // without the risk of scanning out one of those buffers.
6227b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar            pushBlankBuffersToNativeWindow(mCodec->mNativeWindow.get());
6228bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
6229bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
62300806340688c937e7b78c2d89db3809274130df4eLajos Molnar        if (err != OK) {
62310806340688c937e7b78c2d89db3809274130df4eLajos Molnar            mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
62320806340688c937e7b78c2d89db3809274130df4eLajos Molnar            return;
62330806340688c937e7b78c2d89db3809274130df4eLajos Molnar        }
62340806340688c937e7b78c2d89db3809274130df4eLajos Molnar
6235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mIdleToLoadedState);
6236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6239f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onInputBufferFilled(
6240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
6241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
6242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
6244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6246f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onOutputBufferDrained(
6247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
6248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
6249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
6251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
6254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6255f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
6256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
6257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6259f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
6260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
6261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
6263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
6264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
6266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
6272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
6274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
62750806340688c937e7b78c2d89db3809274130df4eLajos Molnar            ALOGE("Got flush request in IdleToLoadedState");
6276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
6281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
6285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6287f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToLoadedState::stateEntered() {
62883856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
6289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6291f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onOMXEvent(
6292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
6294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
6295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
62960806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandStateSet
62970806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    || data2 != (OMX_U32)OMX_StateLoaded) {
62980806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("Unexpected command completion in IdleToLoadedState: %s(%u) %s(%u)",
62990806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1,
63000806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_STATETYPE)data2), data2);
63010806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
63020806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
63030806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6305c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->changeState(mCodec->mLoadedState);
6306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
6312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
6316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6317f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::FlushingState::FlushingState(ACodec *codec)
6318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
6319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6321f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::stateEntered() {
63223856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
6323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
6325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6327f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
6328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
6329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
6331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
6332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
6334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
6338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing this right now.
6340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
6346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
6350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6352f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onOMXEvent(
6353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6354ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGV("[%s] FlushingState onOMXEvent(%u,%d)",
6355ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar            mCodec->mComponentName.c_str(), event, (OMX_S32)data1);
6356d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
6357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
6358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
6359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
63600806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandFlush) {
63610806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("unexpected EventCmdComplete %s(%d) data2:%d in FlushingState",
63620806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1, data2);
63630806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
63640806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
63650806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
6368777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (mFlushComplete[data2]) {
6369777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGW("Flush already completed for %s port",
6370777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            data2 == kPortIndexInput ? "input" : "output");
6371777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return true;
6372777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
6373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mFlushComplete[data2] = true;
6374e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber
63750806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (mFlushComplete[kPortIndexInput] && mFlushComplete[kPortIndexOutput]) {
6376e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                    changeStateIfWeOwnAllBuffers();
6377e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                }
6378777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            } else if (data2 == OMX_ALL) {
6379777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (!mFlushComplete[kPortIndexInput] || !mFlushComplete[kPortIndexOutput]) {
6380777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGW("received flush complete event for OMX_ALL before ports have been"
6381777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            "flushed (%d/%d)",
6382777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mFlushComplete[kPortIndexInput], mFlushComplete[kPortIndexOutput]);
6383777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return false;
6384777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
6385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                changeStateIfWeOwnAllBuffers();
6387777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            } else {
6388777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                ALOGW("data2 not OMX_ALL but %u in EventCmdComplete CommandFlush", data2);
6389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
6390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6394349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
6395349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
63961d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec);
6397349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("type", omx_message::EVENT);
6398609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            msg->setInt32("node", mCodec->mNode);
6399349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("event", event);
6400349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data1", data1);
6401349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data2", data2);
6402349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
64033856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
6404349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                 mCodec->mComponentName.c_str());
6405349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6406349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mCodec->deferMessage(msg);
6407349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6408349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
6409349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
6410349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
6413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
6416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6418f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
6419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
6420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
6422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6424f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
6425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
6426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
6428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6430f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
6431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mFlushComplete[kPortIndexInput]
6432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mFlushComplete[kPortIndexOutput]
6433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mCodec->allYourBuffersAreBelongToUs()) {
64347e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // We now own all buffers except possibly those still queued with
64357e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // the native window for rendering. Let's get those back as well.
64367e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
64377e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
6438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
6439d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatFlushCompleted);
6440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->post();
6441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->mPortEOS[kPortIndexInput] =
6443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mPortEOS[kPortIndexOutput] = false;
6444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6445dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber        mCodec->mInputEOSResult = OK;
6446dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
6447f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        if (mCodec->mSkipCutBuffer != NULL) {
6448f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen            mCodec->mSkipCutBuffer->clear();
6449f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        }
6450f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen
6451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mExecutingState);
6452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
6456