ACodec.cpp revision 777cf6d2788b12bbd68f620cda94a128462a208d
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();
1057054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (info == NULL)
1058054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return ERROR_IO;
1059054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1060609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] submitting output meta buffer ID %u for graphic buffer %p",
1061054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          mComponentName.c_str(), info->mBufferID, info->mGraphicBuffer.get());
1062054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1063054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    --mMetaDataBuffersToSubmit;
1064777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    status_t err = mOMX->fillBuffer(mNode, info->mBufferID);
1065777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (err == OK) {
1066777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
1067777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
1068054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1069777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    return err;
1070054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
1071054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1072f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
1073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
1074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1075609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Calling cancelBuffer on buffer %u",
1076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mComponentName.c_str(), info->mBufferID);
1077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int err = mNativeWindow->cancelBuffer(
10791e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        mNativeWindow.get(), info->mGraphicBuffer.get(), -1);
1080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10813fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia    ALOGW_IF(err != 0, "[%s] can not return buffer %u to native window",
10823fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia            mComponentName.c_str(), info->mBufferID);
1083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
1085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10863fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia    return err;
1087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1089f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
10908ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev    ANativeWindowBuffer *buf;
1091054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mNativeWindow.get() != NULL);
1092ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
1093ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    if (mTunneled) {
1094ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        ALOGW("dequeueBufferFromNativeWindow() should not be called in tunnel"
1095ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad              " video playback mode mode!");
1096ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        return NULL;
1097ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    }
1098ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
1099dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    do {
1100dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        if (native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf) != 0) {
1101dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            ALOGE("dequeueBuffer failed.");
1102dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            return NULL;
1103dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        }
1104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1105dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        bool stale = false;
1106dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
1107dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
1108dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar
1109dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            if (info->mGraphicBuffer != NULL &&
1110dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                info->mGraphicBuffer->handle == buf->handle) {
1111dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // Since consumers can attach buffers to BufferQueues, it is possible
1112dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // that a known yet stale buffer can return from a surface that we
1113dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // once used.  We can simply ignore this as we have already dequeued
1114dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // this buffer properly.  NOTE: this does not eliminate all cases,
1115dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // e.g. it is possible that we have queued the valid buffer to the
1116dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // NW, and a stale copy of the same buffer gets dequeued - which will
1117dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // be treated as the valid buffer by ACodec.
1118dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                if (info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
1119dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                    ALOGI("dequeued stale buffer %p. discarding", buf);
1120dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                    stale = true;
1121dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                    break;
1122dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                }
1123dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                ALOGV("dequeued buffer %p", info->mGraphicBuffer->getNativeBuffer());
1124dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                info->mStatus = BufferInfo::OWNED_BY_US;
1125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1126dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                return info;
1127dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            }
1128dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        }
1129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1130dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // It is also possible to receive a previously unregistered buffer
1131dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // in non-meta mode. These should be treated as stale buffers. The
1132dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // same is possible in meta mode, in which case, it will be treated
1133dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // as a normal buffer, which is not desirable.
1134dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // TODO: fix this.
1135011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        if (!stale && (!mStoreMetaDataInOutputBuffers || mLegacyAdaptiveExperiment)) {
1136dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            ALOGI("dequeued unrecognized (stale) buffer %p. discarding", buf);
1137dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            stale = true;
1138dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        }
1139dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        if (stale) {
1140dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            // TODO: detach stale buffer, but there is no API yet to do it.
1141dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            buf = NULL;
1142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1143dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    } while (buf == NULL);
1144054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1145dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    // get oldest undequeued buffer
1146dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    BufferInfo *oldest = NULL;
1147dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
1148dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        BufferInfo *info =
1149dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            &mBuffers[kPortIndexOutput].editItemAt(i);
1150054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW &&
1151054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (oldest == NULL ||
1152054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             // avoid potential issues from counter rolling over
1153054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mDequeueCounter - info->mDequeuedAt >
1154054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    mDequeueCounter - oldest->mDequeuedAt)) {
1155054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            oldest = info;
1156054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
1157054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1158054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1159054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (oldest) {
1160054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(mStoreMetaDataInOutputBuffers);
1161054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1162054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // discard buffer in LRU info and replace with new buffer
1163054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mGraphicBuffer = new GraphicBuffer(buf, false);
1164054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mStatus = BufferInfo::OWNED_BY_US;
1165054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1166d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        mOMX->updateGraphicBufferInMeta(
1167d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                mNode, kPortIndexOutput, oldest->mGraphicBuffer,
1168d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                oldest->mBufferID);
1169054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1170d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        VideoDecoderOutputMetaData *metaData =
1171d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar            reinterpret_cast<VideoDecoderOutputMetaData *>(
1172d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                    oldest->mData->base());
1173d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        CHECK_EQ(metaData->eType, kMetadataBufferTypeGrallocSource);
1174d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar
1175d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
1176ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                (unsigned)(oldest - &mBuffers[kPortIndexOutput][0]),
1177054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mDequeueCounter - oldest->mDequeuedAt,
1178d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                metaData->pHandle,
1179d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                oldest->mGraphicBuffer->handle, oldest->mData->base());
1180054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1181054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return oldest;
1182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
1185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
1187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1189f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
1190777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    status_t err = OK;
1191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[portIndex].size(); i-- > 0;) {
1192777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        status_t err2 = freeBuffer(portIndex, i);
1193777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        if (err == OK) {
1194777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            err = err2;
1195777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        }
1196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDealer[portIndex].clear();
1199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1200777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    return err;
1201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1203349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huberstatus_t ACodec::freeOutputBuffersNotOwnedByComponent() {
1204777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    status_t err = OK;
1205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
1206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
1207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
1208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
12092ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // At this time some buffers may still be with the component
12102ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // or being drained.
12112ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT &&
12122ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar            info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) {
1213777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            status_t err2 = freeBuffer(kPortIndexOutput, i);
1214777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            if (err == OK) {
1215777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                err = err2;
1216777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            }
1217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1220777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    return err;
1221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1223f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
1224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
1225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(info->mStatus == BufferInfo::OWNED_BY_US
1227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
1228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput && mNativeWindow != NULL
1230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && info->mStatus == BufferInfo::OWNED_BY_US) {
12313fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        cancelBufferToNativeWindow(info);
1232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1234777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    status_t err = mOMX->freeBuffer(mNode, portIndex, info->mBufferID);
1235777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    // remove buffer even if mOMX->freeBuffer fails
1236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mBuffers[portIndex].removeAt(i);
1237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1238777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    return err;
1239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1241f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::findBufferByID(
1242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        uint32_t portIndex, IOMX::buffer_id bufferID,
1243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ssize_t *index) {
1244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
1245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
1246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mBufferID == bufferID) {
1248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (index != NULL) {
1249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                *index = i;
1250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
1252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1255777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    ALOGE("Could not find buffer with ID %u", bufferID);
1256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
1257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
12595778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setComponentRole(
1260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        bool isEncoder, const char *mime) {
1261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    struct MimeToRole {
1262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime;
1263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *decoderRole;
1264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *encoderRole;
1265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
1266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const MimeToRole kMimeToRole[] = {
1268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG,
1269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.mp3", "audio_encoder.mp3" },
12702944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
12712944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp1", "audio_encoder.mp1" },
12722944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
12732944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp2", "audio_encoder.mp2" },
1274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_NB,
1275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrnb", "audio_encoder.amrnb" },
1276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_WB,
1277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrwb", "audio_encoder.amrwb" },
1278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AAC,
1279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.aac", "audio_encoder.aac" },
1280729de186450f78c099637e1fce743fe531862c52Andreas Huber        { MEDIA_MIMETYPE_AUDIO_VORBIS,
1281729de186450f78c099637e1fce743fe531862c52Andreas Huber            "audio_decoder.vorbis", "audio_encoder.vorbis" },
1282bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian        { MEDIA_MIMETYPE_AUDIO_OPUS,
1283bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian            "audio_decoder.opus", "audio_encoder.opus" },
1284c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_MLAW,
1285c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" },
1286c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_ALAW,
1287c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711alaw", "audio_encoder.g711alaw" },
1288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_AVC,
1289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.avc", "video_encoder.avc" },
12902472b1c0d63454e5d90a982bd6c555de6c3127bdRachad        { MEDIA_MIMETYPE_VIDEO_HEVC,
12912472b1c0d63454e5d90a982bd6c555de6c3127bdRachad            "video_decoder.hevc", "video_encoder.hevc" },
1292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_MPEG4,
1293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.mpeg4", "video_encoder.mpeg4" },
1294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_H263,
1295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.h263", "video_encoder.h263" },
129694705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP8,
129794705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp8", "video_encoder.vp8" },
129894705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP9,
129994705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp9", "video_encoder.vp9" },
1300ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        { MEDIA_MIMETYPE_AUDIO_RAW,
1301ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            "audio_decoder.raw", "audio_encoder.raw" },
13022f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        { MEDIA_MIMETYPE_AUDIO_FLAC,
13032f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            "audio_decoder.flac", "audio_encoder.flac" },
1304ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        { MEDIA_MIMETYPE_AUDIO_MSGSM,
1305ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen            "audio_decoder.gsm", "audio_encoder.gsm" },
1306774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu        { MEDIA_MIMETYPE_VIDEO_MPEG2,
1307774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu            "video_decoder.mpeg2", "video_encoder.mpeg2" },
130897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        { MEDIA_MIMETYPE_AUDIO_AC3,
130997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            "audio_decoder.ac3", "audio_encoder.ac3" },
13108a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        { MEDIA_MIMETYPE_AUDIO_EAC3,
13118a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            "audio_decoder.eac3", "audio_encoder.eac3" },
1312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
1313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const size_t kNumMimeToRole =
1315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
1316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    size_t i;
1318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (i = 0; i < kNumMimeToRole; ++i) {
1319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcasecmp(mime, kMimeToRole[i].mime)) {
1320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (i == kNumMimeToRole) {
13255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_UNSUPPORTED;
1326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    const char *role =
1329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        isEncoder ? kMimeToRole[i].encoderRole
1330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                  : kMimeToRole[i].decoderRole;
1331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (role != NULL) {
1333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_PARAM_COMPONENTROLETYPE roleParams;
1334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        InitOMXParams(&roleParams);
1335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        strncpy((char *)roleParams.cRole,
1337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                role, OMX_MAX_STRINGNAME_SIZE - 1);
1338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
1340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->setParameter(
1342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamStandardComponentRole,
1343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &roleParams, sizeof(roleParams));
1344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
13465ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("[%s] Failed to set standard component role '%s'.",
1347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 mComponentName.c_str(), role);
13485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
1350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
13525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
1354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
13565778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::configureCodec(
1357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime, const sp<AMessage> &msg) {
13585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t encoder;
13595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("encoder", &encoder)) {
13605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        encoder = false;
13615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1363e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    sp<AMessage> inputFormat = new AMessage();
13644e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    sp<AMessage> outputFormat = mNotify->dup(); // will use this for kWhatOutputFormatChanged
1365e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
13665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mIsEncoder = encoder;
1367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
13688db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu
13695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setComponentRole(encoder /* isEncoder */, mime);
13705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
13725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
13735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
13745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitRate = 0;
13762f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    // FLAC encoder doesn't need a bitrate, other encoders do
13772f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
13782f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            && !msg->findInt32("bitrate", &bitRate)) {
13795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
13805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
13815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1382d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    int32_t storeMeta;
1383d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (encoder
1384d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && msg->findInt32("store-metadata-in-buffers", &storeMeta)
1385d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && storeMeta != 0) {
1386d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE);
1387d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1388d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (err != OK) {
1389308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              ALOGE("[%s] storeMetaDataInBuffers (input) failed w/ err %d",
1390308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    mComponentName.c_str(), err);
1391d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1392308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              return err;
1393308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang          }
1394308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang      }
1395d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1396308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t prependSPSPPS = 0;
13973a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    if (encoder
13983a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
13993a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && prependSPSPPS != 0) {
14003a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        OMX_INDEXTYPE index;
14013a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        err = mOMX->getExtensionIndex(
14023a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                mNode,
14033a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                "OMX.google.android.index.prependSPSPPSToIDRFrames",
14043a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                &index);
14053a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
14063a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err == OK) {
14073a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            PrependSPSPPSToIDRFramesParams params;
14083a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            InitOMXParams(&params);
14093a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            params.bEnable = OMX_TRUE;
14103a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
14113a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            err = mOMX->setParameter(
14123a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                    mNode, index, &params, sizeof(params));
14133a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
14143a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
14153a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err != OK) {
14163a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            ALOGE("Encoder could not be configured to emit SPS/PPS before "
14173a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                  "IDR frames. (err %d)", err);
14183a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
14193a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            return err;
14203a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
14213a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    }
14223a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
1423308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // Only enable metadata mode on encoder output if encoder can prepend
1424308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // sps/pps to idr frames, since in metadata mode the bitstream is in an
1425308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // opaque handle, to which we don't have access.
1426308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t video = !strncasecmp(mime, "video/", 6);
14278db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    mIsVideo = video;
1428308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (encoder && video) {
1429308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS
1430308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && msg->findInt32("store-metadata-in-buffers-output", &storeMeta)
1431308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && storeMeta != 0);
1432308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1433308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, enable);
1434308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1435308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        if (err != OK) {
1436308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            ALOGE("[%s] storeMetaDataInBuffers (output) failed w/ err %d",
1437308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                mComponentName.c_str(), err);
1438308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = 0;
1439308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        } else {
1440308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = enable;
1441308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        }
1442a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
1443a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (!msg->findInt64(
1444a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    "repeat-previous-frame-after",
1445a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    &mRepeatFrameDelayUs)) {
1446a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            mRepeatFrameDelayUs = -1ll;
1447a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
144894ee4b708acfa941581160b267afb79192b1d816Chong Zhang
144994ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (!msg->findInt64("max-pts-gap-to-encoder", &mMaxPtsGapUs)) {
14502c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mMaxPtsGapUs = -1ll;
14512c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
14522c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
145337b2b389139ed638831e49708c947863eef631efRonghua Wu        if (!msg->findFloat("max-fps-to-encoder", &mMaxFps)) {
145437b2b389139ed638831e49708c947863eef631efRonghua Wu            mMaxFps = -1;
145537b2b389139ed638831e49708c947863eef631efRonghua Wu        }
145637b2b389139ed638831e49708c947863eef631efRonghua Wu
14572c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (!msg->findInt64("time-lapse", &mTimePerCaptureUs)) {
14582c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mTimePerCaptureUs = -1ll;
145994ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
146072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
146172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (!msg->findInt32(
146272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    "create-input-buffers-suspended",
146372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    (int32_t*)&mCreateInputBuffersSuspended)) {
146472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mCreateInputBuffersSuspended = false;
146572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
1466308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    }
1467308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
14683a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar    // NOTE: we only use native window for video decoders
1469054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    sp<RefBase> obj;
14700d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    bool haveNativeWindow = msg->findObject("native-window", &obj)
14713a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            && obj != NULL && video && !encoder;
1472054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mStoreMetaDataInOutputBuffers = false;
1473011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar    mLegacyAdaptiveExperiment = false;
1474e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if (video && !encoder) {
1475e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        inputFormat->setInt32("adaptive-playback", false);
14761713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang
14771713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        int32_t usageProtected;
14781713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        if (msg->findInt32("protected", &usageProtected) && usageProtected) {
14791713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            if (!haveNativeWindow) {
14801713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang                ALOGE("protected output buffers must be sent to an ANativeWindow");
14811713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang                return PERMISSION_DENIED;
14821713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            }
14831713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            mFlags |= kFlagIsGrallocUsageProtected;
14841713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
14851713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        }
1486e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
14873a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar    if (haveNativeWindow) {
14881de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar        sp<ANativeWindow> nativeWindow =
14891de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar            static_cast<ANativeWindow *>(static_cast<Surface *>(obj.get()));
14905a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
14916597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        // START of temporary support for automatic FRC - THIS WILL BE REMOVED
14926597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        int32_t autoFrc;
14936597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        if (msg->findInt32("auto-frc", &autoFrc)) {
14946597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            bool enabled = autoFrc;
14956597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            OMX_CONFIG_BOOLEANTYPE config;
14966597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            InitOMXParams(&config);
14976597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            config.bEnabled = (OMX_BOOL)enabled;
14986597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            status_t temp = mOMX->setConfig(
14996597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                    mNode, (OMX_INDEXTYPE)OMX_IndexConfigAutoFramerateConversion,
15006597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                    &config, sizeof(config));
15016597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            if (temp == OK) {
15026597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                outputFormat->setInt32("auto-frc", enabled);
15036597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            } else if (enabled) {
15046597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                ALOGI("codec does not support requested auto-frc (err %d)", temp);
15056597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            }
15066597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        }
15076597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        // END of temporary support for automatic FRC
15086597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar
15095a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        int32_t tunneled;
15105a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        if (msg->findInt32("feature-tunneled-playback", &tunneled) &&
15115a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            tunneled != 0) {
15125a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            ALOGI("Configuring TUNNELED video playback.");
1513ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            mTunneled = true;
15145a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
151597827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad            int32_t audioHwSync = 0;
151697827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad            if (!msg->findInt32("audio-hw-sync", &audioHwSync)) {
15175a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGW("No Audio HW Sync provided for video tunnel");
15185a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            }
15195a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            err = configureTunneledVideoPlayback(audioHwSync, nativeWindow);
15205a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (err != OK) {
152197827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad                ALOGE("configureTunneledVideoPlayback(%d,%p) failed!",
15225a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        audioHwSync, nativeWindow.get());
15235a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                return err;
1524fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
1525fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1526d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            int32_t maxWidth = 0, maxHeight = 0;
1527d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            if (msg->findInt32("max-width", &maxWidth) &&
1528d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    msg->findInt32("max-height", &maxHeight)) {
1529d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad
1530d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                err = mOMX->prepareForAdaptivePlayback(
1531d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                        mNode, kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight);
1532d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                if (err != OK) {
1533d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    ALOGW("[%s] prepareForAdaptivePlayback failed w/ err %d",
1534d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                            mComponentName.c_str(), err);
15353a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    // allow failure
15363a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    err = OK;
1537d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                } else {
1538d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("max-width", maxWidth);
1539d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("max-height", maxHeight);
1540d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("adaptive-playback", true);
1541d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                }
1542d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            }
15435a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        } else {
1544ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            ALOGV("Configuring CPU controlled video playback.");
1545ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            mTunneled = false;
1546ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
15473fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // Explicity reset the sideband handle of the window for
15483fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // non-tunneled video in case the window was previously used
15493fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // for a tunneled video playback.
15503fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            err = native_window_set_sideband_stream(nativeWindow.get(), NULL);
15513fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            if (err != OK) {
15523fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad                ALOGE("set_sideband_stream(NULL) failed! (err %d).", err);
15533fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad                return err;
15543fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            }
15553fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad
15565a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            // Always try to enable dynamic output buffers on native surface
15575a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            err = mOMX->storeMetaDataInBuffers(
15585a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    mNode, kPortIndexOutput, OMX_TRUE);
15595a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (err != OK) {
15605a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d",
1561fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        mComponentName.c_str(), err);
1562e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
15635a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // if adaptive playback has been requested, try JB fallback
15645a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // NOTE: THIS FALLBACK MECHANISM WILL BE REMOVED DUE TO ITS
15655a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // LARGE MEMORY REQUIREMENT
15665a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
15675a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // we will not do adaptive playback on software accessed
15685a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // surfaces as they never had to respond to changes in the
15695a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // crop window, and we don't trust that they will be able to.
15705a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                int usageBits = 0;
15715a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                bool canDoAdaptivePlayback;
15725a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
15735a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                if (nativeWindow->query(
15745a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        nativeWindow.get(),
15755a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        NATIVE_WINDOW_CONSUMER_USAGE_BITS,
15765a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        &usageBits) != OK) {
15775a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    canDoAdaptivePlayback = false;
15785a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                } else {
15795a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    canDoAdaptivePlayback =
15805a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        (usageBits &
15815a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                                (GRALLOC_USAGE_SW_READ_MASK |
15825a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                                 GRALLOC_USAGE_SW_WRITE_MASK)) == 0;
15835a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                }
15845a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
15855a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                int32_t maxWidth = 0, maxHeight = 0;
15865a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                if (canDoAdaptivePlayback &&
15875a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        msg->findInt32("max-width", &maxWidth) &&
15885a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        msg->findInt32("max-height", &maxHeight)) {
15895a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    ALOGV("[%s] prepareForAdaptivePlayback(%dx%d)",
15905a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mComponentName.c_str(), maxWidth, maxHeight);
15915a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
15925a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    err = mOMX->prepareForAdaptivePlayback(
15935a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mNode, kPortIndexOutput, OMX_TRUE, maxWidth,
15945a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            maxHeight);
15955a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    ALOGW_IF(err != OK,
15965a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            "[%s] prepareForAdaptivePlayback failed w/ err %d",
15975a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mComponentName.c_str(), err);
15985a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
15995a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    if (err == OK) {
16005a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("max-width", maxWidth);
16015a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("max-height", maxHeight);
16025a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("adaptive-playback", true);
16035a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    }
1604e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
16055a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // allow failure
16065a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                err = OK;
16075a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            } else {
16085a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGV("[%s] storeMetaDataInBuffers succeeded",
16095a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        mComponentName.c_str());
16105a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                mStoreMetaDataInOutputBuffers = true;
1611011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                mLegacyAdaptiveExperiment = ADebug::isExperimentEnabled(
1612011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                        "legacy-adaptive", !msg->contains("no-experiments"));
1613011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
16145a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                inputFormat->setInt32("adaptive-playback", true);
1615fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
16160167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber
16175a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            int32_t push;
16185a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (msg->findInt32("push-blank-buffers-on-shutdown", &push)
16195a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    && push != 0) {
16205a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
16215a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            }
16220167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        }
1623e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang
1624e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        int32_t rotationDegrees;
1625e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        if (msg->findInt32("rotation-degrees", &rotationDegrees)) {
1626e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            mRotationDegrees = rotationDegrees;
1627e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        } else {
1628e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            mRotationDegrees = 0;
1629e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        }
1630054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1631054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1632308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (video) {
16333a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // determine need for software renderer
16343a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        bool usingSwRenderer = false;
16353a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (haveNativeWindow && mComponentName.startsWith("OMX.google.")) {
16363a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            usingSwRenderer = true;
16373a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            haveNativeWindow = false;
16383a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
16393a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
16405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (encoder) {
16415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupVideoEncoder(mime, msg);
16425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
16430d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            err = setupVideoDecoder(mime, msg, haveNativeWindow);
16445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16453a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
16463a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (err != OK) {
16473a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            return err;
16483a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
16493a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
16503a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (haveNativeWindow) {
16511de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar            mNativeWindow = static_cast<Surface *>(obj.get());
16523a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
16533a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
16543a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // initialize native window now to get actual output format
16553a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // TODO: this is needed for some encoders even though they don't use native window
1656777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        err = initNativeWindow();
1657777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        if (err != OK) {
1658777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return err;
1659777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        }
16603a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
16613a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // fallback for devices that do not handle flex-YUV for native buffers
16623a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (haveNativeWindow) {
16633a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            int32_t requestedColorFormat = OMX_COLOR_FormatUnused;
16643a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            if (msg->findInt32("color-format", &requestedColorFormat) &&
16653a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    requestedColorFormat == OMX_COLOR_FormatYUV420Flexible) {
1666777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                status_t err = getPortFormat(kPortIndexOutput, outputFormat);
1667777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (err != OK) {
1668777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return err;
1669777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
16703a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                int32_t colorFormat = OMX_COLOR_FormatUnused;
16713a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                OMX_U32 flexibleEquivalent = OMX_COLOR_FormatUnused;
1672777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (!outputFormat->findInt32("color-format", &colorFormat)) {
1673777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGE("ouptut port did not have a color format (wrong domain?)");
1674777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return BAD_VALUE;
1675777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
16763a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                ALOGD("[%s] Requested output format %#x and got %#x.",
16773a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        mComponentName.c_str(), requestedColorFormat, colorFormat);
16783a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                if (!isFlexibleColorFormat(
16793a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                                mOMX, mNode, colorFormat, haveNativeWindow, &flexibleEquivalent)
16803a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        || flexibleEquivalent != (OMX_U32)requestedColorFormat) {
16813a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    // device did not handle flex-YUV request for native window, fall back
16823a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    // to SW renderer
16833a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    ALOGI("[%s] Falling back to software renderer", mComponentName.c_str());
16843a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    mNativeWindow.clear();
16853a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    haveNativeWindow = false;
16863a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    usingSwRenderer = true;
16873a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    if (mStoreMetaDataInOutputBuffers) {
16883a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, OMX_FALSE);
16893a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        mStoreMetaDataInOutputBuffers = false;
16903a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        // TODO: implement adaptive-playback support for bytebuffer mode.
16913a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        // This is done by SW codecs, but most HW codecs don't support it.
16923a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        inputFormat->setInt32("adaptive-playback", false);
16933a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
16943a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    if (err == OK) {
16953a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        err = mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
16963a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
16973a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    if (mFlags & kFlagIsGrallocUsageProtected) {
16983a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        // fallback is not supported for protected playback
16993a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        err = PERMISSION_DENIED;
17003a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    } else if (err == OK) {
17013a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        err = setupVideoDecoder(mime, msg, false);
17023a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
17033a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                }
17043a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            }
17053a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
17063a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
17073a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (usingSwRenderer) {
17083a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            outputFormat->setInt32("using-sw-renderer", 1);
17093a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
171042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
171142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        int32_t numChannels, sampleRate;
171242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        if (!msg->findInt32("channel-count", &numChannels)
171342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
171442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // Since we did not always check for these, leave them optional
171542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // and have the decoder figure it all out.
171642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = OK;
171742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        } else {
171842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = setupRawAudioFormat(
171942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    encoder ? kPortIndexInput : kPortIndexOutput,
172042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    sampleRate,
172142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    numChannels);
172242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        }
1723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
1724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t numChannels, sampleRate;
17255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)
17265778822d86b0337407514b9372562b86edfa91cdAndreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
17275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
17285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
1729aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            int32_t isADTS, aacProfile;
1730b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            int32_t sbrMode;
17318045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            int32_t maxOutputChannelCount;
17322965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            int32_t pcmLimiterEnable;
17338045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            drcParams_t drc;
1734ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            if (!msg->findInt32("is-adts", &isADTS)) {
1735ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                isADTS = 0;
1736ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
1737aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (!msg->findInt32("aac-profile", &aacProfile)) {
1738aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                aacProfile = OMX_AUDIO_AACObjectNull;
1739aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
1740b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            if (!msg->findInt32("aac-sbr-mode", &sbrMode)) {
1741b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                sbrMode = -1;
1742b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            }
1743ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
17448045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-max-output-channel_count", &maxOutputChannelCount)) {
17458045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                maxOutputChannelCount = -1;
17468045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
17472965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            if (!msg->findInt32("aac-pcm-limiter-enable", &pcmLimiterEnable)) {
17482965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                // value is unknown
17492965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                pcmLimiterEnable = -1;
17502965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            }
17518045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-encoded-target-level", &drc.encodedTargetLevel)) {
17528045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
17538045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.encodedTargetLevel = -1;
17548045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
17558045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-cut-level", &drc.drcCut)) {
17568045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
17578045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.drcCut = -1;
17588045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
17598045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-boost-level", &drc.drcBoost)) {
17608045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
17618045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.drcBoost = -1;
17628045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
17638045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-heavy-compression", &drc.heavyCompression)) {
17648045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
17658045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.heavyCompression = -1;
17668045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
17678045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-target-ref-level", &drc.targetRefLevel)) {
17688045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
17698045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.targetRefLevel = -1;
17708045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
17718045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi
1772ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            err = setupAACCodec(
17734471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    encoder, numChannels, sampleRate, bitRate, aacProfile,
17742965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                    isADTS != 0, sbrMode, maxOutputChannelCount, drc,
17752965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                    pcmLimiterEnable);
17765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
1777729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
17785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
1779729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
17805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
1781729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
1782729de186450f78c099637e1fce743fe531862c52Andreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
1783729de186450f78c099637e1fce743fe531862c52Andreas Huber        // These are PCM-like formats with a fixed sample rate but
1784729de186450f78c099637e1fce743fe531862c52Andreas Huber        // a variable number of channels.
1785729de186450f78c099637e1fce743fe531862c52Andreas Huber
1786729de186450f78c099637e1fce743fe531862c52Andreas Huber        int32_t numChannels;
17875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)) {
17885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
17895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
179017c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            int32_t sampleRate;
179117c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            if (!msg->findInt32("sample-rate", &sampleRate)) {
179217c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen                sampleRate = 8000;
179317c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            }
179417c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            err = setupG711Codec(encoder, sampleRate, numChannels);
17955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17962f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
1797ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        int32_t numChannels = 0, sampleRate = 0, compressionLevel = -1;
17982f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (encoder &&
17992f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                (!msg->findInt32("channel-count", &numChannels)
18002f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                        || !msg->findInt32("sample-rate", &sampleRate))) {
18012f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("missing channel count or sample rate for FLAC encoder");
18022f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            err = INVALID_OPERATION;
18032f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        } else {
18042f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            if (encoder) {
1805516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                if (!msg->findInt32(
1806cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                            "complexity", &compressionLevel) &&
1807cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                    !msg->findInt32(
1808516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                            "flac-compression-level", &compressionLevel)) {
1809cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                    compressionLevel = 5; // default FLAC compression level
18102f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel < 0) {
1811516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1812516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 0",
1813516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
18142f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 0;
18152f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel > 8) {
1816516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1817516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 8",
1818516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
18192f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 8;
18202f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                }
18212f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            }
1822516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            err = setupFlacCodec(
1823516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    encoder, numChannels, sampleRate, compressionLevel);
18242f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
1825ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
1826ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        int32_t numChannels, sampleRate;
1827ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        if (encoder
1828ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("channel-count", &numChannels)
1829ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
1830ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = INVALID_OPERATION;
1831ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        } else {
1832ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
1833ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        }
183497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AC3)) {
183597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t numChannels;
183697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t sampleRate;
183797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        if (!msg->findInt32("channel-count", &numChannels)
183897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                || !msg->findInt32("sample-rate", &sampleRate)) {
183997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = INVALID_OPERATION;
184097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        } else {
184197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = setupAC3Codec(encoder, numChannels, sampleRate);
184297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        }
18438a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_EAC3)) {
18448a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        int32_t numChannels;
18458a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        int32_t sampleRate;
18468a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        if (!msg->findInt32("channel-count", &numChannels)
18478a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                || !msg->findInt32("sample-rate", &sampleRate)) {
18488a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            err = INVALID_OPERATION;
18498a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        } else {
18508a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            err = setupEAC3Codec(encoder, numChannels, sampleRate);
18518a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        }
18525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1853729de186450f78c099637e1fce743fe531862c52Andreas Huber
18544471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    if (err != OK) {
18554471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber        return err;
18564471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    }
18574471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber
18588b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
18598b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderDelay = 0;
18608b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
18619806555d3930be43e11106281dee354820ac1c88Andreas Huber
18628b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
18638b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderPadding = 0;
18648b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
18658b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen
18669806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (msg->findInt32("channel-mask", &mChannelMask)) {
18679806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = true;
18689806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else {
18699806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = false;
18709806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
18719806555d3930be43e11106281dee354820ac1c88Andreas Huber
1872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t maxInputSize;
1873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (msg->findInt32("max-input-size", &maxInputSize)) {
18745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
1875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
18765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
1877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
18785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18798b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    int32_t priority;
18808b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    if (msg->findInt32("priority", &priority)) {
18818b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu        err = setPriority(priority);
18828b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    }
18838b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu
1884ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    int32_t rateInt = -1;
1885ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    float rateFloat = -1;
1886ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (!msg->findFloat("operating-rate", &rateFloat)) {
1887ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        msg->findInt32("operating-rate", &rateInt);
1888ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        rateFloat = (float)rateInt;  // 16MHz (FLINTMAX) is OK for upper bound.
1889ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
1890ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (rateFloat > 0) {
1891ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        err = setOperatingRate(rateFloat, video);
1892ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
1893ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu
18944e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    mBaseOutputFormat = outputFormat;
18954e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar
1896777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    err = getPortFormat(kPortIndexInput, inputFormat);
1897777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (err == OK) {
1898777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        err = getPortFormat(kPortIndexOutput, outputFormat);
1899777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        if (err == OK) {
1900777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            mInputFormat = inputFormat;
1901777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            mOutputFormat = outputFormat;
1902777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        }
1903777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
19045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
1905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
19078b806ea894ca098366629458bfdd1df4866afcdfRonghua Wustatus_t ACodec::setPriority(int32_t priority) {
19088b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    if (priority < 0) {
19098b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu        return BAD_VALUE;
19108b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    }
19118b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    OMX_PARAM_U32TYPE config;
19128b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    InitOMXParams(&config);
19138b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    config.nU32 = (OMX_U32)priority;
19148b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    status_t temp = mOMX->setConfig(
19158b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu            mNode, (OMX_INDEXTYPE)OMX_IndexConfigPriority,
19168b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu            &config, sizeof(config));
19178b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    if (temp != OK) {
19188b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu        ALOGI("codec does not support config priority (err %d)", temp);
19198b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    }
19208b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    return OK;
19218b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu}
19228b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu
1923ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wustatus_t ACodec::setOperatingRate(float rateFloat, bool isVideo) {
1924ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (rateFloat < 0) {
1925ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        return BAD_VALUE;
1926ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
1927ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    OMX_U32 rate;
1928ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (isVideo) {
1929ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        if (rateFloat > 65535) {
1930ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            return BAD_VALUE;
1931ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        }
1932ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        rate = (OMX_U32)(rateFloat * 65536.0f + 0.5f);
1933ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    } else {
1934ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        if (rateFloat > UINT_MAX) {
1935ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            return BAD_VALUE;
1936ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        }
1937ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        rate = (OMX_U32)(rateFloat);
1938ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
1939ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    OMX_PARAM_U32TYPE config;
1940ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    InitOMXParams(&config);
1941ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    config.nU32 = rate;
1942ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    status_t err = mOMX->setConfig(
1943ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            mNode, (OMX_INDEXTYPE)OMX_IndexConfigOperatingRate,
1944ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            &config, sizeof(config));
1945ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (err != OK) {
1946ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        ALOGI("codec does not support config operating rate (err %d)", err);
1947ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
1948ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    return OK;
1949ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu}
1950ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu
1951f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
1952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
1954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
1955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (def.nBufferSize >= size) {
1964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
1965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nBufferSize = size;
1968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
1970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->getParameter(
1977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1983777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (def.nBufferSize < size) {
1984777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("failed to set min buffer size to %zu (is still %u)", size, def.nBufferSize);
1985777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return FAILED_TRANSACTION;
1986777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
1987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
19915778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::selectAudioPortFormat(
19925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
19935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_AUDIO_PARAM_PORTFORMATTYPE format;
19945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&format);
19955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    format.nPortIndex = portIndex;
19975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (OMX_U32 index = 0;; ++index) {
19985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        format.nIndex = index;
19995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
20015778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioPortFormat,
20025778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &format, sizeof(format));
20035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
20055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
20065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (format.eEncoding == desiredFormat) {
20095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
20105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
20145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format));
20155778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
20165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20175778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAACCodec(
2018aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        bool encoder, int32_t numChannels, int32_t sampleRate,
20198045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        int32_t bitRate, int32_t aacProfile, bool isADTS, int32_t sbrMode,
20202965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang        int32_t maxOutputChannelCount, const drcParams_t& drc,
20212965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang        int32_t pcmLimiterEnable) {
2022ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (encoder && isADTS) {
2023ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return -EINVAL;
2024ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
2025ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
20265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setupRawAudioFormat(
20275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
20285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sampleRate,
20295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            numChannels);
20305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (encoder) {
20365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
20375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
20395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
20405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
20435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
20445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = kPortIndexOutput;
20455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
20475778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
20485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
20505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
20515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.bFlagErrorConcealment = OMX_TRUE;
20545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
20555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
20575778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
20585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
20605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
20615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
20645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&profile);
20655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nPortIndex = kPortIndexOutput;
20665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
20685778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
20695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
20715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
20725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nChannels = numChannels;
20755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eChannelMode =
20775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (numChannels == 1)
20785778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
20795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nSampleRate = sampleRate;
20815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nBitRate = bitRate;
20825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAudioBandWidth = 0;
20835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nFrameLength = 0;
20845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACtools = OMX_AUDIO_AACToolAll;
20855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACERtools = OMX_AUDIO_AACERNone;
2086aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
20875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
2088b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        switch (sbrMode) {
2089b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 0:
2090b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // disable sbr
2091b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
2092b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
2093b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2094b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 1:
2095b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable single-rate sbr
2096b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
2097b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
2098b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2099b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 2:
2100b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable dual-rate sbr
2101b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
2102b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
2103b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2104b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case -1:
2105b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable both modes -> the codec will decide which mode should be used
2106b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
2107b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
2108b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2109b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        default:
2110b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // unsupported sbr mode
2111b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            return BAD_VALUE;
2112b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        }
2113b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi
21145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
21165778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
21175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
21195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
21205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_AUDIO_PARAM_AACPROFILETYPE profile;
2126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&profile);
2127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nPortIndex = kPortIndexInput;
2128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
21295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
2130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
2131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nChannels = numChannels;
2137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nSampleRate = sampleRate;
2138ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2139ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    profile.eAACStreamFormat =
2140ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        isADTS
2141ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            ? OMX_AUDIO_AACStreamFormatMP4ADTS
2142ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            : OMX_AUDIO_AACStreamFormatMP4FF;
2143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
21448045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    OMX_AUDIO_PARAM_ANDROID_AACPRESENTATIONTYPE presentation;
21458045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nMaxOutputChannels = maxOutputChannelCount;
21468045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nDrcCut = drc.drcCut;
21478045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nDrcBoost = drc.drcBoost;
21488045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nHeavyCompression = drc.heavyCompression;
21498045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nTargetReferenceLevel = drc.targetRefLevel;
21508045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nEncodedTargetLevel = drc.encodedTargetLevel;
21512965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang    presentation.nPCMLimiterEnable = pcmLimiterEnable;
21528045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi
21538045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    status_t res = mOMX->setParameter(mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
21548045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    if (res == OK) {
21558045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        // optional parameters, will not cause configuration failure
21568045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        mOMX->setParameter(mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAacPresentation,
21578045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                &presentation, sizeof(presentation));
21588045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    } else {
21598045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        ALOGW("did not set AudioAndroidAacPresentation due to error %d when setting AudioAac", res);
21608045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    }
21618045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    return res;
21625778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
2163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
216497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryustatus_t ACodec::setupAC3Codec(
216597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        bool encoder, int32_t numChannels, int32_t sampleRate) {
216697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    status_t err = setupRawAudioFormat(
216797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
216897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
216997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
217097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
217197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
217297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
217397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (encoder) {
217497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        ALOGW("AC3 encoding is not supported.");
217597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return INVALID_OPERATION;
217697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
217797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
217897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    OMX_AUDIO_PARAM_ANDROID_AC3TYPE def;
217997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    InitOMXParams(&def);
218097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nPortIndex = kPortIndexInput;
218197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
218297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    err = mOMX->getParameter(
218397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
218497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
218597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
218697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
218797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
218897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
218997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
219097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
219197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
219297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nChannels = numChannels;
219397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nSampleRate = sampleRate;
219497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
219597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    return mOMX->setParameter(
219697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
219797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
219897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
219997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
220097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu}
220197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
22028a4728966dc9c78e21c3c93a927707e93c05e5e0Rachadstatus_t ACodec::setupEAC3Codec(
22038a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        bool encoder, int32_t numChannels, int32_t sampleRate) {
22048a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    status_t err = setupRawAudioFormat(
22058a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
22068a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
22078a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (err != OK) {
22088a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return err;
22098a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
22108a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
22118a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (encoder) {
22128a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        ALOGW("EAC3 encoding is not supported.");
22138a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return INVALID_OPERATION;
22148a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
22158a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
22168a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    OMX_AUDIO_PARAM_ANDROID_EAC3TYPE def;
22178a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    InitOMXParams(&def);
22188a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nPortIndex = kPortIndexInput;
22198a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
22208a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    err = mOMX->getParameter(
22218a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            mNode,
22228a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
22238a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            &def,
22248a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            sizeof(def));
22258a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
22268a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (err != OK) {
22278a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return err;
22288a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
22298a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
22308a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nChannels = numChannels;
22318a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nSampleRate = sampleRate;
22328a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
22338a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    return mOMX->setParameter(
22348a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            mNode,
22358a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
22368a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            &def,
22378a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            sizeof(def));
22388a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad}
22398a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
22405778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
22415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        bool isAMRWB, int32_t bps) {
22425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (isAMRWB) {
22435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 6600) {
22445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB0;
22455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 8850) {
22465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB1;
22475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 12650) {
22485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB2;
22495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 14250) {
22505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB3;
22515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 15850) {
22525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB4;
22535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 18250) {
22545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB5;
22555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 19850) {
22565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB6;
22575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 23050) {
22585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB7;
22595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 23850 bps
22625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeWB8;
22635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {  // AMRNB
22645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 4750) {
22655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB0;
22665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5150) {
22675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB1;
22685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5900) {
22695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB2;
22705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 6700) {
22715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB3;
22725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7400) {
22735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB4;
22745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7950) {
22755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB5;
22765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 10200) {
22775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB6;
22785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 12200 bps
22815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeNB7;
22825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
22855778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
2286729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_AMRTYPE def;
2287729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
22885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
2289729de186450f78c099637e1fce743fe531862c52Andreas Huber
2290729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err =
2291729de186450f78c099637e1fce743fe531862c52Andreas Huber        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
2292729de186450f78c099637e1fce743fe531862c52Andreas Huber
2293729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2294729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2295729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2296729de186450f78c099637e1fce743fe531862c52Andreas Huber
2297729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
22985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
22995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
23015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
2302729de186450f78c099637e1fce743fe531862c52Andreas Huber
23035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
23045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
23055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2306729de186450f78c099637e1fce743fe531862c52Andreas Huber
23075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupRawAudioFormat(
23085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
23095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            isWAMR ? 16000 : 8000 /* sampleRate */,
23105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            1 /* numChannels */);
2311729de186450f78c099637e1fce743fe531862c52Andreas Huber}
2312729de186450f78c099637e1fce743fe531862c52Andreas Huber
231317c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissenstatus_t ACodec::setupG711Codec(bool encoder, int32_t sampleRate, int32_t numChannels) {
2314777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (encoder) {
2315777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return INVALID_OPERATION;
2316777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
23175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2318729de186450f78c099637e1fce743fe531862c52Andreas Huber    return setupRawAudioFormat(
231917c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            kPortIndexInput, sampleRate, numChannels);
2320729de186450f78c099637e1fce743fe531862c52Andreas Huber}
2321729de186450f78c099637e1fce743fe531862c52Andreas Huber
23222f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivistatus_t ACodec::setupFlacCodec(
23232f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
23242f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
23252f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder) {
23262f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        OMX_AUDIO_PARAM_FLACTYPE def;
23272f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        InitOMXParams(&def);
23282f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nPortIndex = kPortIndexOutput;
23292f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
23302f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        // configure compression level
23312f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        status_t err = mOMX->getParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
23322f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
23332f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
23342f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
23352f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
23362f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nCompressionLevel = compressionLevel;
23372f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        err = mOMX->setParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
23382f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
23392f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
23402f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
23412f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
23422f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
23432f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
23442f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    return setupRawAudioFormat(
23452f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            encoder ? kPortIndexInput : kPortIndexOutput,
23462f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            sampleRate,
23472f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            numChannels);
23482f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi}
23492f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
2350729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t ACodec::setupRawAudioFormat(
2351729de186450f78c099637e1fce743fe531862c52Andreas Huber        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
2352729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
2353729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
2354729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.nPortIndex = portIndex;
2355729de186450f78c099637e1fce743fe531862c52Andreas Huber
2356729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err = mOMX->getParameter(
2357729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2358729de186450f78c099637e1fce743fe531862c52Andreas Huber
2359729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2360729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2361729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2362729de186450f78c099637e1fce743fe531862c52Andreas Huber
2363729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
2364729de186450f78c099637e1fce743fe531862c52Andreas Huber
2365729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->setParameter(
2366729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2367729de186450f78c099637e1fce743fe531862c52Andreas Huber
2368729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2369729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2370729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2371729de186450f78c099637e1fce743fe531862c52Andreas Huber
2372729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
2373729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&pcmParams);
2374729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nPortIndex = portIndex;
2375729de186450f78c099637e1fce743fe531862c52Andreas Huber
2376729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->getParameter(
2377729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
2378729de186450f78c099637e1fce743fe531862c52Andreas Huber
2379729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2380729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2381729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2382729de186450f78c099637e1fce743fe531862c52Andreas Huber
2383729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nChannels = numChannels;
2384729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.eNumData = OMX_NumericalDataSigned;
2385729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.bInterleaved = OMX_TRUE;
2386729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nBitPerSample = 16;
2387729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nSamplingRate = sampleRate;
2388729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
2389729de186450f78c099637e1fce743fe531862c52Andreas Huber
2390c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber    if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
2391c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber        return OMX_ErrorNone;
2392729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2393729de186450f78c099637e1fce743fe531862c52Andreas Huber
2394729de186450f78c099637e1fce743fe531862c52Andreas Huber    return mOMX->setParameter(
2395729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
2396729de186450f78c099637e1fce743fe531862c52Andreas Huber}
2397729de186450f78c099637e1fce743fe531862c52Andreas Huber
23985a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachadstatus_t ACodec::configureTunneledVideoPlayback(
239997827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad        int32_t audioHwSync, const sp<ANativeWindow> &nativeWindow) {
24005a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    native_handle_t* sidebandHandle;
24015a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
24025a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    status_t err = mOMX->configureVideoTunnelMode(
24035a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            mNode, kPortIndexOutput, OMX_TRUE, audioHwSync, &sidebandHandle);
24045a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    if (err != OK) {
24055a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        ALOGE("configureVideoTunnelMode failed! (err %d).", err);
24065a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        return err;
24075a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    }
24085a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
24095a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    err = native_window_set_sideband_stream(nativeWindow.get(), sidebandHandle);
24105a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    if (err != OK) {
24115a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        ALOGE("native_window_set_sideband_stream(%p) failed! (err %d).",
24125a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                sidebandHandle, err);
24135a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        return err;
24145a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    }
24155a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
24165a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    return OK;
24175a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad}
24185a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
2419f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoPortFormatType(
2420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
2421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_VIDEO_CODINGTYPE compressionFormat,
24220d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        OMX_COLOR_FORMATTYPE colorFormat,
24230d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        bool usingNativeBuffers) {
2424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
2425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
2426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = portIndex;
2427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
2428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool found = false;
2429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 index = 0;
2431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (;;) {
2432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        format.nIndex = index;
2433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->getParameter(
2434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamVideoPortFormat,
2435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &format, sizeof(format));
2436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
2438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return err;
2439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2441229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        // substitute back flexible color format to codec supported format
2442229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        OMX_U32 flexibleEquivalent;
24430d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (compressionFormat == OMX_VIDEO_CodingUnused
24440d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && isFlexibleColorFormat(
24450d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        mOMX, mNode, format.eColorFormat, usingNativeBuffers, &flexibleEquivalent)
24460d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && colorFormat == flexibleEquivalent) {
2447229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            ALOGI("[%s] using color format %#x in place of %#x",
2448229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                    mComponentName.c_str(), format.eColorFormat, colorFormat);
2449229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            colorFormat = format.eColorFormat;
2450229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
2451229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
2452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The following assertion is violated by TI's video decoder.
2453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // CHECK_EQ(format.nIndex, index);
2454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
2456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexInput
2457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && colorFormat == format.eColorFormat) {
2458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eCompressionFormat does not seem right.
2459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
2460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
2461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexOutput
2463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && compressionFormat == format.eCompressionFormat) {
2464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eColorFormat does not seem right.
2465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
2466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
2467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (format.eCompressionFormat == compressionFormat
2471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && format.eColorFormat == colorFormat) {
2472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            found = true;
2473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ++index;
2477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!found) {
2480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return UNKNOWN_ERROR;
2481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->setParameter(
2484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
2485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
2486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
2488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
24900d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// Set optimal output format. OMX component lists output formats in the order
24910d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// of preference, but this got more complicated since the introduction of flexible
24920d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// YUV formats. We support a legacy behavior for applications that do not use
24930d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// surface output, do not specify an output format, but expect a "usable" standard
24940d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// OMX format. SW readable and standard formats must be flex-YUV.
24950d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar//
24960d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// Suggested preference order:
24970d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal format for texture rendering (mediaplayer behavior)
24980d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal SW readable & texture renderable format (flex-YUV support)
24990d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal SW readable non-renderable format (flex-YUV bytebuffer support)
25000d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - legacy "usable" standard formats
25010d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar//
25020d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// For legacy support, we prefer a standard format, but will settle for a SW readable
25030d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// flex-YUV format.
25040d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnarstatus_t ACodec::setSupportedOutputFormat(bool getLegacyFlexibleFormat) {
25050d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    OMX_VIDEO_PARAM_PORTFORMATTYPE format, legacyFormat;
2506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
2507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = kPortIndexOutput;
2508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
25090d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    InitOMXParams(&legacyFormat);
25100d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    // this field will change when we find a suitable legacy format
25110d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    legacyFormat.eColorFormat = OMX_COLOR_FormatUnused;
2512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
25130d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    for (OMX_U32 index = 0; ; ++index) {
25140d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        format.nIndex = index;
25150d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        status_t err = mOMX->getParameter(
25160d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                mNode, OMX_IndexParamVideoPortFormat,
25170d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                &format, sizeof(format));
25180d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (err != OK) {
25190d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            // no more formats, pick legacy format if found
25200d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            if (legacyFormat.eColorFormat != OMX_COLOR_FormatUnused) {
25210d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                 memcpy(&format, &legacyFormat, sizeof(format));
25220d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                 break;
25230d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            }
25240d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            return err;
25250d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
25260d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (format.eCompressionFormat != OMX_VIDEO_CodingUnused) {
25270d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            return OMX_ErrorBadParameter;
25280d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
25290d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (!getLegacyFlexibleFormat) {
25300d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            break;
25310d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
25320d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        // standard formats that were exposed to users before
25330d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (format.eColorFormat == OMX_COLOR_FormatYUV420Planar
25340d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_COLOR_FormatYUV420PackedPlanar
25350d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar
25360d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_COLOR_FormatYUV420PackedSemiPlanar
25370d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar) {
25380d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            break;
25390d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
25400d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        // find best legacy non-standard format
25410d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        OMX_U32 flexibleEquivalent;
25420d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (legacyFormat.eColorFormat == OMX_COLOR_FormatUnused
25430d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && isFlexibleColorFormat(
25440d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        mOMX, mNode, format.eColorFormat, false /* usingNativeBuffers */,
25450d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        &flexibleEquivalent)
25460d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && flexibleEquivalent == OMX_COLOR_FormatYUV420Flexible) {
25470d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            memcpy(&legacyFormat, &format, sizeof(format));
25480d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
25490d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    }
2550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mOMX->setParameter(
2551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
2552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
2553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2555e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic const struct VideoCodingMapEntry {
2556e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    const char *mMime;
2557e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    OMX_VIDEO_CODINGTYPE mVideoCodingType;
2558e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber} kVideoCodingMapEntry[] = {
2559e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC },
25602472b1c0d63454e5d90a982bd6c555de6c3127bdRachad    { MEDIA_MIMETYPE_VIDEO_HEVC, OMX_VIDEO_CodingHEVC },
2561e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 },
2562e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 },
2563e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 },
256494705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 },
256594705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 },
2566e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber};
2567e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
25685778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic status_t GetVideoCodingTypeFromMime(
25695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
2570e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
2571e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
2572e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
2573e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) {
2574e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *codingType = kVideoCodingMapEntry[i].mVideoCodingType;
2575e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
2576e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
2577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2579e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    *codingType = OMX_VIDEO_CodingUnused;
2580e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2581e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
2582e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
2583e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2584e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic status_t GetMimeTypeForVideoCoding(
2585e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        OMX_VIDEO_CODINGTYPE codingType, AString *mime) {
2586e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
2587e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
2588e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
2589e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) {
2590e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *mime = kVideoCodingMapEntry[i].mMime;
2591e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
2592e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
2593e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
2594e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2595e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    mime->clear();
2596e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2597e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
25985778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
25995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26005778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoDecoder(
26010d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        const char *mime, const sp<AMessage> &msg, bool haveNativeWindow) {
260289869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    int32_t width, height;
260389869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    if (!msg->findInt32("width", &width)
260489869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            || !msg->findInt32("height", &height)) {
260589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        return INVALID_OPERATION;
260689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    }
260789869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar
26085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
26095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
26105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
26125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
26135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
2616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
2617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
262289869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    int32_t tmp;
262389869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    if (msg->findInt32("color-format", &tmp)) {
262489869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        OMX_COLOR_FORMATTYPE colorFormat =
262589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            static_cast<OMX_COLOR_FORMATTYPE>(tmp);
262689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        err = setVideoPortFormatType(
26270d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                kPortIndexOutput, OMX_VIDEO_CodingUnused, colorFormat, haveNativeWindow);
262889869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        if (err != OK) {
262989869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            ALOGW("[%s] does not support color format %d",
263089869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar                  mComponentName.c_str(), colorFormat);
26310d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            err = setSupportedOutputFormat(!haveNativeWindow /* getLegacyFlexibleFormat */);
263289869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        }
263389869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    } else {
26340d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        err = setSupportedOutputFormat(!haveNativeWindow /* getLegacyFlexibleFormat */);
263589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    }
2636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
264178b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    int32_t frameRateInt;
264278b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    float frameRateFloat;
264378b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    if (!msg->findFloat("frame-rate", &frameRateFloat)) {
264478b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        if (!msg->findInt32("frame-rate", &frameRateInt)) {
264578b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            frameRateInt = -1;
264678b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        }
264778b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        frameRateFloat = (float)frameRateInt;
264878b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    }
264978b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad
2650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
265178b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            kPortIndexInput, width, height, compressionFormat, frameRateFloat);
2652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
2658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
2659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
26675778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) {
26685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
26695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("color-format", &tmp)) {
26705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
26715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_COLOR_FORMATTYPE colorFormat =
26745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        static_cast<OMX_COLOR_FORMATTYPE>(tmp);
26755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setVideoPortFormatType(
26775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
26785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
26805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support color format %d",
26815778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str(), colorFormat);
26825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
26845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Input port configuration */
26875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
26895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&def);
26905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
26925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexInput;
26945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
26965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
26975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
26995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
27005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t width, height, bitrate;
27035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("width", &width)
27045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("height", &height)
27055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("bitrate", &bitrate)) {
27065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
27075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
27105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
27115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t stride;
27135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("stride", &stride)) {
27145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        stride = width;
27155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nStride = stride;
27185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t sliceHeight;
27205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("slice-height", &sliceHeight)) {
27215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sliceHeight = height;
27225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nSliceHeight = sliceHeight;
27255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
27275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
27295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
27305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
27315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
27325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
27335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
27345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
27352c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        mTimePerFrameUs = (int64_t) (1000000.0f / frameRate);
27365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
27395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
2740a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    // this is redundant as it was already set up in setVideoPortFormatType
2741a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    // FIXME for now skip this only for flexible YUV formats
2742a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    if (colorFormat != OMX_COLOR_FormatYUV420Flexible) {
2743a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar        video_def->eColorFormat = colorFormat;
2744a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    }
27455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
27475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
27485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
27505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set input port definition parameters.",
27515778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
27525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
27545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Output port configuration */
27575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
27595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
27605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
27625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
27635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
27665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
27675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
27695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support compression format %d",
27705778822d86b0337407514b9372562b86edfa91cdAndreas Huber             mComponentName.c_str(), compressionFormat);
27715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
27735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexOutput;
27765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
27785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
27795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
27815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
27825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
27855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
27865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = 0;
27875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nBitrate = bitrate;
27885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = compressionFormat;
27895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = OMX_COLOR_FormatUnused;
27905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
27925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
27935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
27955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set output port definition parameters.",
27965778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
27975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
27995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (compressionFormat) {
28025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingMPEG4:
28035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupMPEG4EncoderParameters(msg);
28045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
28055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingH263:
28075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupH263EncoderParameters(msg);
28085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
28095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingAVC:
28115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupAVCEncoderParameters(msg);
28125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
28135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2814c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        case OMX_VIDEO_CodingHEVC:
2815c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            err = setupHEVCEncoderParameters(msg);
2816c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            break;
2817c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
281889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP8:
281989b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP9:
282089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            err = setupVPXEncoderParameters(msg);
282189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            break;
282289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
28235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
28245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
28255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGI("setupVideoEncoder succeeded");
28285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
28305778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
28315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28320dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dongstatus_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) {
28330dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    OMX_VIDEO_PARAM_INTRAREFRESHTYPE params;
28340dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    InitOMXParams(&params);
28350dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.nPortIndex = kPortIndexOutput;
28360dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
28370dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode);
28380dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
28390dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic ||
28400dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
28410dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
28420dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) {
28430dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
28440dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
28450dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nCirMBs = mbs;
28460dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
28470dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
28480dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive ||
28490dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
28500dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
28510dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) {
28520dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
28530dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
28540dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirMBs = mbs;
28550dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
28560dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t ref;
28570dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) {
28580dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
28590dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
28600dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirRef = ref;
28610dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
28620dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
28630dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = mOMX->setParameter(
28640dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            mNode, OMX_IndexParamVideoIntraRefresh,
28650dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            &params, sizeof(params));
28660dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    return err;
28670dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong}
28680dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
28695778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
28705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (iFramesInterval < 0) {
28715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0xFFFFFFFF;
28725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (iFramesInterval == 0) {
28735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0;
28745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_U32 ret = frameRate * iFramesInterval;
28765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return ret;
28775778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
28785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
287996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatic OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) {
288096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    int32_t tmp;
288196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    if (!msg->findInt32("bitrate-mode", &tmp)) {
288296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        return OMX_Video_ControlRateVariable;
288396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    }
288496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
288596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp);
288696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber}
288796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
28885778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
28895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
28905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
28915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
28925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
28935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
289596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
289696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
28975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
28985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
28995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
29005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
29015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
29025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
29035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
29045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
29075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&mpeg4type);
29085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPortIndex = kPortIndexOutput;
29095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
29115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
29125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
29145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
29155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nSliceHeaderSpacing = 0;
29185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bSVH = OMX_FALSE;
29195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bGov = OMX_FALSE;
29205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nAllowedPictureTypes =
29225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
29235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
29255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mpeg4type.nPFrames == 0) {
29265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
29275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nBFrames = 0;
29295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nIDCVLCThreshold = 0;
29305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bACPred = OMX_TRUE;
29315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nMaxPacketSize = 256;
29325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nTimeIncRes = 1000;
29335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nHeaderExtension = 0;
29345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bReversibleVLC = OMX_FALSE;
29355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
29375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
29385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
29395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
29405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
29415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
29425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
29445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
29465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
29475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
29485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
29505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
29515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
29545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
29555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
29575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
29585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
296096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
29615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
29635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
29645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
29675778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
29685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29695778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
29705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
29715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
29725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
29735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
29745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
297696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
297796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
29785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
29795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
29805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
29815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
29825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
29835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
29845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
29855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_H263TYPE h263type;
29885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h263type);
29895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPortIndex = kPortIndexOutput;
29905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
29925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
29935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
29955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
29965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nAllowedPictureTypes =
29995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
30005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
30025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h263type.nPFrames == 0) {
30035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
30045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
30055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nBFrames = 0;
30065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
30085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
30095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
30105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
30115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
30125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
30135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
30155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
30175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
30185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
30195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
30215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
30225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
30235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bPLUSPTYPEAllowed = OMX_FALSE;
30255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bForceRoundingTypeToZero = OMX_FALSE;
30265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPictureHeaderRepetition = 0;
30275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nGOBHeaderInterval = 0;
30285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
30305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
30315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
30335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
30345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
30355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
303696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
30375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
30395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
30405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
30415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
30435778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
30445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3045a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar// static
3046a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnarint /* OMX_VIDEO_AVCLEVELTYPE */ ACodec::getAVCLevelFor(
3047a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        int width, int height, int rate, int bitrate,
3048a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        OMX_VIDEO_AVCPROFILETYPE profile) {
3049a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    // convert bitrate to main/baseline profile kbps equivalent
3050a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    switch (profile) {
3051a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        case OMX_VIDEO_AVCProfileHigh10:
3052a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 3000); break;
3053a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        case OMX_VIDEO_AVCProfileHigh:
3054a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 1250); break;
3055a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        default:
3056a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 1000); break;
3057a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    }
3058a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
3059a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    // convert size and rate to MBs
3060a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    width = divUp(width, 16);
3061a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    height = divUp(height, 16);
3062a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    int mbs = width * height;
3063a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    rate *= mbs;
3064a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    int maxDimension = max(width, height);
3065a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
3066a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    static const int limits[][5] = {
3067a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        /*   MBps     MB   dim  bitrate        level */
3068a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    1485,    99,  28,     64, OMX_VIDEO_AVCLevel1  },
3069a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    1485,    99,  28,    128, OMX_VIDEO_AVCLevel1b },
3070a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    3000,   396,  56,    192, OMX_VIDEO_AVCLevel11 },
3071a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    6000,   396,  56,    384, OMX_VIDEO_AVCLevel12 },
3072a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   11880,   396,  56,    768, OMX_VIDEO_AVCLevel13 },
3073a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   11880,   396,  56,   2000, OMX_VIDEO_AVCLevel2  },
3074a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   19800,   792,  79,   4000, OMX_VIDEO_AVCLevel21 },
3075a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   20250,  1620, 113,   4000, OMX_VIDEO_AVCLevel22 },
3076a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   40500,  1620, 113,  10000, OMX_VIDEO_AVCLevel3  },
3077a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  108000,  3600, 169,  14000, OMX_VIDEO_AVCLevel31 },
3078a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  216000,  5120, 202,  20000, OMX_VIDEO_AVCLevel32 },
3079a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  245760,  8192, 256,  20000, OMX_VIDEO_AVCLevel4  },
3080a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  245760,  8192, 256,  50000, OMX_VIDEO_AVCLevel41 },
3081a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  522240,  8704, 263,  50000, OMX_VIDEO_AVCLevel42 },
3082a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  589824, 22080, 420, 135000, OMX_VIDEO_AVCLevel5  },
3083a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  983040, 36864, 543, 240000, OMX_VIDEO_AVCLevel51 },
3084a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        { 2073600, 36864, 543, 240000, OMX_VIDEO_AVCLevel52 },
3085a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    };
3086a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
3087a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    for (size_t i = 0; i < ARRAY_SIZE(limits); i++) {
3088a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        const int (&limit)[5] = limits[i];
3089a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        if (rate <= limit[0] && mbs <= limit[1] && maxDimension <= limit[2]
3090a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar                && bitrate <= limit[3]) {
3091a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            return limit[4];
3092a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        }
3093a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    }
3094a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    return 0;
3095a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar}
3096a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
30975778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
30985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
30995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
31005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
31015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
31025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
31035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
310496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
310596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
31065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
31075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
31085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
31095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
31105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
31115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
31125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
31135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
31145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31150dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = OK;
31160dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    int32_t intraRefreshMode = 0;
31170dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) {
31180dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode);
31190dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (err != OK) {
31200dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
31210dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong                    err, intraRefreshMode);
31220dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return err;
31230dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
31240dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
31250dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
31265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_AVCTYPE h264type;
31275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h264type);
31285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nPortIndex = kPortIndexOutput;
31295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31300dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    err = mOMX->getParameter(
31315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
31325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
31345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
31355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
31365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nAllowedPictureTypes =
31385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
31395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
31415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
31425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
31435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
31445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
31455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
31465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
31485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
31505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
31515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
31525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
31545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
31555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
31565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // XXX
31587c25df82dfc8bbedb58608242f0d923a4594bb14James Dong    if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) {
31597c25df82dfc8bbedb58608242f0d923a4594bb14James Dong        ALOGW("Use baseline profile instead of %d for AVC recording",
31607c25df82dfc8bbedb58608242f0d923a4594bb14James Dong            h264type.eProfile);
31615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
31625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
31635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
31655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nSliceHeaderSpacing = 0;
31665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bUseHadamard = OMX_TRUE;
31675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefFrames = 1;
31685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nBFrames = 0;
31695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
31705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (h264type.nPFrames == 0) {
31715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
31725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
31735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx10ActiveMinus1 = 0;
31745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx11ActiveMinus1 = 0;
31755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bEntropyCodingCABAC = OMX_FALSE;
31765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bWeightedPPrediction = OMX_FALSE;
31775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bconstIpred = OMX_FALSE;
31785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirect8x8Inference = OMX_FALSE;
31795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirectSpatialTemporal = OMX_FALSE;
31805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nCabacInitIdc = 0;
31815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
31825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.nBFrames != 0) {
31845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
31855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
31865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableUEP = OMX_FALSE;
31885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableFMO = OMX_FALSE;
31895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableASO = OMX_FALSE;
31905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableRS = OMX_FALSE;
31915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bFrameMBsOnly = OMX_TRUE;
31925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bMBAFF = OMX_FALSE;
31935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
31945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
31965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
31975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
31995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
32005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
32015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
320296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return configureBitrate(bitrate, bitrateMode);
32035778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
32045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3205c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachadstatus_t ACodec::setupHEVCEncoderParameters(const sp<AMessage> &msg) {
3206c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    int32_t bitrate, iFrameInterval;
3207c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findInt32("bitrate", &bitrate)
3208c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
3209c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return INVALID_OPERATION;
3210c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
3211c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3212c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
3213c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3214c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    float frameRate;
3215c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findFloat("frame-rate", &frameRate)) {
3216c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t tmp;
3217c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("frame-rate", &tmp)) {
3218c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
3219c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
3220c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        frameRate = (float)tmp;
3221c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
3222c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3223c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_PARAM_HEVCTYPE hevcType;
3224c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    InitOMXParams(&hevcType);
3225c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    hevcType.nPortIndex = kPortIndexOutput;
3226c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3227c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    status_t err = OK;
3228c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    err = mOMX->getParameter(
3229c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
3230c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
3231c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
3232c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
3233c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3234c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    int32_t profile;
3235c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (msg->findInt32("profile", &profile)) {
3236c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t level;
3237c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("level", &level)) {
3238c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
3239c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
3240c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3241c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        err = verifySupportForProfileAndLevel(profile, level);
3242c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (err != OK) {
3243c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return err;
3244c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
3245c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3246c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eProfile = static_cast<OMX_VIDEO_HEVCPROFILETYPE>(profile);
3247c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eLevel = static_cast<OMX_VIDEO_HEVCLEVELTYPE>(level);
3248c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
3249c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3250c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    // TODO: Need OMX structure definition for setting iFrameInterval
3251c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3252c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    err = mOMX->setParameter(
3253c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
3254c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
3255c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
3256c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
3257c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3258c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    return configureBitrate(bitrate, bitrateMode);
3259c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad}
3260c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
326189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huberstatus_t ACodec::setupVPXEncoderParameters(const sp<AMessage> &msg) {
326289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    int32_t bitrate;
32634154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    int32_t iFrameInterval = 0;
32644154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    size_t tsLayers = 0;
32654154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE pattern =
32664154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        OMX_VIDEO_VPXTemporalLayerPatternNone;
32674154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    static const uint32_t kVp8LayerRateAlloction
32684154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS]
32694154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS] = {
32704154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        {100, 100, 100},  // 1 layer
32714154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 60, 100, 100},  // 2 layers {60%, 40%}
32724154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 40,  60, 100},  // 3 layers {40%, 20%, 40%}
32734154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    };
327489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    if (!msg->findInt32("bitrate", &bitrate)) {
327589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        return INVALID_OPERATION;
327689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    }
32774154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    msg->findInt32("i-frame-interval", &iFrameInterval);
327889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
327989b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
328089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
32814154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    float frameRate;
32824154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (!msg->findFloat("frame-rate", &frameRate)) {
32834154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        int32_t tmp;
32844154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (!msg->findInt32("frame-rate", &tmp)) {
32854154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            return INVALID_OPERATION;
32864154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
32874154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        frameRate = (float)tmp;
32884154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
32894154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
32904154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    AString tsSchema;
32914154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (msg->findString("ts-schema", &tsSchema)) {
32924154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (tsSchema == "webrtc.vp8.1-layer") {
32934154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
32944154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 1;
32954154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else if (tsSchema == "webrtc.vp8.2-layer") {
32964154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
32974154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 2;
32984154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else if (tsSchema == "webrtc.vp8.3-layer") {
32994154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
33004154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 3;
33014154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else {
33024154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            ALOGW("Unsupported ts-schema [%s]", tsSchema.c_str());
33034154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
33044154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
33054154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
33064154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
33074154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    InitOMXParams(&vp8type);
33084154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    vp8type.nPortIndex = kPortIndexOutput;
33094154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    status_t err = mOMX->getParameter(
33104154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
33114154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            &vp8type, sizeof(vp8type));
33124154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
33134154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (err == OK) {
33144154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (iFrameInterval > 0) {
33154154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nKeyFrameInterval = setPFramesSpacing(iFrameInterval, frameRate);
33164154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
33174154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.eTemporalPattern = pattern;
33184154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.nTemporalLayerCount = tsLayers;
33194154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (tsLayers > 0) {
33204154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            for (size_t i = 0; i < OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS; i++) {
33214154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                vp8type.nTemporalLayerBitrateRatio[i] =
33224154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                    kVp8LayerRateAlloction[tsLayers - 1][i];
33234154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            }
33244154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
33254154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (bitrateMode == OMX_Video_ControlRateConstant) {
33264154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMinQuantizer = 2;
33274154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMaxQuantizer = 63;
33284154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
33294154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
33304154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        err = mOMX->setParameter(
33314154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
33324154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                &vp8type, sizeof(vp8type));
33334154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (err != OK) {
33344154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            ALOGW("Extended VP8 parameters set failed: %d", err);
33354154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
33364154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
33374154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
333889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    return configureBitrate(bitrate, bitrateMode);
333989b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber}
334089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
33415778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::verifySupportForProfileAndLevel(
33425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t profile, int32_t level) {
33435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
33445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&params);
33455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    params.nPortIndex = kPortIndexOutput;
33465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (params.nProfileIndex = 0;; ++params.nProfileIndex) {
33485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
33495778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode,
33505778822d86b0337407514b9372562b86edfa91cdAndreas Huber                OMX_IndexParamVideoProfileLevelQuerySupported,
33515778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &params,
33525778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sizeof(params));
33535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
33555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
33565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
33575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
33595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
33605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (profile == supportedProfile && level <= supportedLevel) {
33625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OK;
33635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
33645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
33655778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
33665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
336796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatus_t ACodec::configureBitrate(
336896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) {
33695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
33705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&bitrateType);
33715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
33725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
33745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
33755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
33765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
33785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
33795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
33805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
338196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    bitrateType.eControlRate = bitrateMode;
33825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nTargetBitrate = bitrate;
33835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
33855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
33865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
33875778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
33885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33895778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupErrorCorrectionParameters() {
33905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
33915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&errorCorrectionType);
33925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nPortIndex = kPortIndexOutput;
33935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
33955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
33965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
33975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
33995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OK;  // Optional feature. Ignore this failure
34005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
34015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableHEC = OMX_FALSE;
34035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableResync = OMX_TRUE;
34045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nResynchMarkerSpacing = 256;
34055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
34065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableRVLC = OMX_FALSE;
34075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
34095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
34105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
34115778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
34125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3413f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoFormatOnPort(
3414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
341578b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat,
341678b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        float frameRate) {
3417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
3418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
3419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
3420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
3422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
3424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
3425777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (err != OK) {
3426777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return err;
3427777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
3428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
3430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // XXX Need a (much) better heuristic to compute input buffer sizes.
3431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const size_t X = 64 * 1024;
3432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (def.nBufferSize < X) {
3433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.nBufferSize = X;
3434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3437777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (def.eDomain != OMX_PortDomainVideo) {
3438777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("expected video port, got %s(%d)", asString(def.eDomain), def.eDomain);
3439777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return FAILED_TRANSACTION;
3440777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
3441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameWidth = width;
3443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameHeight = height;
3444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
3446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eCompressionFormat = compressionFormat;
3447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eColorFormat = OMX_COLOR_FormatUnused;
344878b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        if (frameRate >= 0) {
344978b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
345078b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        }
3451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
3454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
3455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
3457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3459f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::initNativeWindow() {
3460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL) {
3461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
3462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
3465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
3466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3468d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Hubersize_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
3469d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    size_t n = 0;
3470d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
3471d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
3472d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        const BufferInfo &info = mBuffers[portIndex].itemAt(i);
3473d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
3474d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
3475d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            ++n;
3476d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        }
3477d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    }
3478d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
3479d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    return n;
3480d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber}
3481d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
34827e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubersize_t ACodec::countBuffersOwnedByNativeWindow() const {
34837e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    size_t n = 0;
34847e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
34857e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
34867e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
34877e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
34887e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
34897e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            ++n;
34907e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        }
34917e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
34927e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
34937e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    return n;
34947e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
34957e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
34967e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubervoid ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
34977e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (mNativeWindow == NULL) {
34987e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        return;
34997e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
35007e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
3501e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    while (countBuffersOwnedByNativeWindow() > mNumUndequeuedBuffers
35027e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            && dequeueBufferFromNativeWindow() != NULL) {
3503c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        // these buffers will be submitted as regular buffers; account for this
3504c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        if (mStoreMetaDataInOutputBuffers && mMetaDataBuffersToSubmit > 0) {
3505c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar            --mMetaDataBuffersToSubmit;
3506c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        }
35077e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
35087e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
35097e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
3510f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs(
3511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
3512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
3513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
3514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus != BufferInfo::OWNED_BY_US
3516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3517609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGV("[%s] Buffer %u on port %u still has status %d",
3518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mComponentName.c_str(),
3519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info->mBufferID, portIndex, info->mStatus);
3520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
3521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3527f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs() {
3528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return allYourBuffersAreBelongToUs(kPortIndexInput)
3529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        && allYourBuffersAreBelongToUs(kPortIndexOutput);
3530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3532f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::deferMessage(const sp<AMessage> &msg) {
3533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.push_back(msg);
3534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3536f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::processDeferredMessages() {
3537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> > queue = mDeferredQueue;
3538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.clear();
3539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> >::iterator it = queue.begin();
3541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while (it != queue.end()) {
3542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        onMessageReceived(*it++);
3543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
354603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar// static
3547229d242665c612fd97431d1e7ac004823b47f181Lajos Molnarbool ACodec::describeDefaultColorFormat(DescribeColorFormatParams &params) {
354803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    MediaImage &image = params.sMediaImage;
354903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    memset(&image, 0, sizeof(image));
355003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
355103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mType = MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
355203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mNumPlanes = 0;
355303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
355403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    const OMX_COLOR_FORMATTYPE fmt = params.eColorFormat;
355503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mWidth = params.nFrameWidth;
355603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mHeight = params.nFrameHeight;
355703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
355803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    // only supporting YUV420
355903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    if (fmt != OMX_COLOR_FormatYUV420Planar &&
356003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        fmt != OMX_COLOR_FormatYUV420PackedPlanar &&
356103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        fmt != OMX_COLOR_FormatYUV420SemiPlanar &&
35625a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        fmt != OMX_COLOR_FormatYUV420PackedSemiPlanar &&
35635a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        fmt != HAL_PIXEL_FORMAT_YV12) {
356403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        ALOGW("do not know color format 0x%x = %d", fmt, fmt);
3565229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return false;
356603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    }
356703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
3568b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    // TEMPORARY FIX for some vendors that advertise sliceHeight as 0
3569b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    if (params.nStride != 0 && params.nSliceHeight == 0) {
3570b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        ALOGW("using sliceHeight=%u instead of what codec advertised (=0)",
3571b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar                params.nFrameHeight);
3572b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        params.nSliceHeight = params.nFrameHeight;
3573b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    }
3574b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar
3575b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    // we need stride and slice-height to be non-zero
3576b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    if (params.nStride == 0 || params.nSliceHeight == 0) {
3577b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        ALOGW("cannot describe color format 0x%x = %d with stride=%u and sliceHeight=%u",
3578b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar                fmt, fmt, params.nStride, params.nSliceHeight);
3579b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        return false;
3580b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    }
3581b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar
358203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    // set-up YUV format
358303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mType = MediaImage::MEDIA_IMAGE_TYPE_YUV;
358403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mNumPlanes = 3;
358503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mBitDepth = 8;
358603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mOffset = 0;
358703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mColInc = 1;
358803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mRowInc = params.nStride;
358903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mHorizSubsampling = 1;
359003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mVertSubsampling = 1;
359103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
35925a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar    switch ((int)fmt) {
35935a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        case HAL_PIXEL_FORMAT_YV12:
35945a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            if (params.bUsingNativeBuffers) {
35955a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                size_t ystride = align(params.nStride, 16);
35965a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                size_t cstride = align(params.nStride / 2, 16);
35975a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.Y].mRowInc = ystride;
35985a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
35995a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mOffset = ystride * params.nSliceHeight;
36005a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mColInc = 1;
36015a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mRowInc = cstride;
36025a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mHorizSubsampling = 2;
36035a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mVertSubsampling = 2;
36045a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
36055a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mOffset = image.mPlane[image.V].mOffset
36065a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                        + (cstride * params.nSliceHeight / 2);
36075a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mColInc = 1;
36085a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mRowInc = cstride;
36095a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mHorizSubsampling = 2;
36105a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mVertSubsampling = 2;
36115a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                break;
36125a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            } else {
36135a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                // fall through as YV12 is used for YUV420Planar by some codecs
36145a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            }
36155a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
36165a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        case OMX_COLOR_FormatYUV420Planar:
361703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420PackedPlanar:
361803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight;
361903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mColInc = 1;
362003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mRowInc = params.nStride / 2;
362103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mHorizSubsampling = 2;
362203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mVertSubsampling = 2;
362303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
362403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset
362503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    + (params.nStride * params.nSliceHeight / 4);
362603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mColInc = 1;
362703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mRowInc = params.nStride / 2;
362803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mHorizSubsampling = 2;
362903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mVertSubsampling = 2;
363003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            break;
363103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
363203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420SemiPlanar:
363303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            // FIXME: NV21 for sw-encoder, NV12 for decoder and hw-encoder
363403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420PackedSemiPlanar:
363503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            // NV12
363603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight;
363703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mColInc = 2;
363803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mRowInc = params.nStride;
363903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mHorizSubsampling = 2;
364003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mVertSubsampling = 2;
364103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
364203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset + 1;
364303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mColInc = 2;
364403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mRowInc = params.nStride;
364503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mHorizSubsampling = 2;
364603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mVertSubsampling = 2;
364703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            break;
364803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
364903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        default:
365003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            TRESPASS();
365103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    }
3652229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    return true;
3653229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar}
3654229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3655229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar// static
3656229d242665c612fd97431d1e7ac004823b47f181Lajos Molnarbool ACodec::describeColorFormat(
3657229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        const sp<IOMX> &omx, IOMX::node_id node,
3658229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        DescribeColorFormatParams &describeParams)
3659229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar{
3660229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    OMX_INDEXTYPE describeColorFormatIndex;
3661229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    if (omx->getExtensionIndex(
3662229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            node, "OMX.google.android.index.describeColorFormat",
3663229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            &describeColorFormatIndex) != OK ||
3664229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        omx->getParameter(
3665229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            node, describeColorFormatIndex,
3666229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            &describeParams, sizeof(describeParams)) != OK) {
3667229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return describeDefaultColorFormat(describeParams);
3668229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    }
3669229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    return describeParams.sMediaImage.mType !=
3670229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
3671229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar}
3672229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3673229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar// static
3674229d242665c612fd97431d1e7ac004823b47f181Lajos Molnarbool ACodec::isFlexibleColorFormat(
3675229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar         const sp<IOMX> &omx, IOMX::node_id node,
36760d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar         uint32_t colorFormat, bool usingNativeBuffers, OMX_U32 *flexibleEquivalent) {
3677229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    DescribeColorFormatParams describeParams;
3678229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    InitOMXParams(&describeParams);
3679229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.eColorFormat = (OMX_COLOR_FORMATTYPE)colorFormat;
3680229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    // reasonable dummy values
3681229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nFrameWidth = 128;
3682229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nFrameHeight = 128;
3683229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nStride = 128;
3684229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nSliceHeight = 128;
36850d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    describeParams.bUsingNativeBuffers = (OMX_BOOL)usingNativeBuffers;
3686229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3687229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    CHECK(flexibleEquivalent != NULL);
3688229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3689229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    if (!describeColorFormat(omx, node, describeParams)) {
3690229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return false;
3691229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    }
3692229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3693229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    const MediaImage &img = describeParams.sMediaImage;
3694229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    if (img.mType == MediaImage::MEDIA_IMAGE_TYPE_YUV) {
3695229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        if (img.mNumPlanes != 3 ||
3696229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            img.mPlane[img.Y].mHorizSubsampling != 1 ||
3697229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            img.mPlane[img.Y].mVertSubsampling != 1) {
3698229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            return false;
3699229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
3700229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3701229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        // YUV 420
3702229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        if (img.mPlane[img.U].mHorizSubsampling == 2
3703229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.U].mVertSubsampling == 2
3704229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.V].mHorizSubsampling == 2
3705229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.V].mVertSubsampling == 2) {
3706229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            // possible flexible YUV420 format
3707229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            if (img.mBitDepth <= 8) {
3708229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar               *flexibleEquivalent = OMX_COLOR_FormatYUV420Flexible;
3709229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar               return true;
3710229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            }
3711229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
3712229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    }
3713229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    return false;
371403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar}
371503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
3716e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarstatus_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> &notify) {
3717777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    const char *niceIndex = portIndex == kPortIndexInput ? "input" : "output";
371831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
371931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    InitOMXParams(&def);
3720e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    def.nPortIndex = portIndex;
372131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3722777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    status_t err = mOMX->getParameter(mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
3723777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (err != OK) {
3724777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return err;
3725777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
372631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3727777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (def.eDir != (portIndex == kPortIndexOutput ? OMX_DirOutput : OMX_DirInput)) {
3728777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("unexpected dir: %s(%d) on %s port", asString(def.eDir), def.eDir, niceIndex);
3729777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return BAD_VALUE;
3730777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
373131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
373231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    switch (def.eDomain) {
373331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainVideo:
373431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
373531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
3736e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            switch ((int)videoDef->eCompressionFormat) {
3737e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_VIDEO_CodingUnused:
3738e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3739e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(mIsEncoder ^ (portIndex == kPortIndexOutput));
3740e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
3741e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3742e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("stride", videoDef->nStride);
3743e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("slice-height", videoDef->nSliceHeight);
3744e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("color-format", videoDef->eColorFormat);
3745e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
37460d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                    if (mNativeWindow == NULL) {
37470d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        DescribeColorFormatParams describeParams;
37480d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        InitOMXParams(&describeParams);
37490d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.eColorFormat = videoDef->eColorFormat;
37500d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nFrameWidth = videoDef->nFrameWidth;
37510d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nFrameHeight = videoDef->nFrameHeight;
37520d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nStride = videoDef->nStride;
37530d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nSliceHeight = videoDef->nSliceHeight;
37540d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.bUsingNativeBuffers = OMX_FALSE;
37550d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar
37560d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        if (describeColorFormat(mOMX, mNode, describeParams)) {
37570d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                            notify->setBuffer(
37580d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                    "image-data",
37590d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                    ABuffer::CreateAsCopy(
37600d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                            &describeParams.sMediaImage,
37610d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                            sizeof(describeParams.sMediaImage)));
37625a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
37635a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                            MediaImage *img = &describeParams.sMediaImage;
37645a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                            ALOGV("[%s] MediaImage { F(%zux%zu) @%zu+%zu+%zu @%zu+%zu+%zu @%zu+%zu+%zu }",
37655a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                                    mComponentName.c_str(), img->mWidth, img->mHeight,
37665a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                                    img->mPlane[0].mOffset, img->mPlane[0].mColInc, img->mPlane[0].mRowInc,
37675a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                                    img->mPlane[1].mOffset, img->mPlane[1].mColInc, img->mPlane[1].mRowInc,
37685a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                                    img->mPlane[2].mOffset, img->mPlane[2].mColInc, img->mPlane[2].mRowInc);
37690d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        }
377003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    }
377103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
377291a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                    if (portIndex != kPortIndexOutput) {
377391a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                        // TODO: also get input crop
377491a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                        break;
377591a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                    }
377691a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar
3777e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_CONFIG_RECTTYPE rect;
3778e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&rect);
377991a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                    rect.nPortIndex = portIndex;
3780e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3781e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    if (mOMX->getConfig(
378291a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                mNode,
378391a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                (portIndex == kPortIndexOutput ?
378491a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                        OMX_IndexConfigCommonOutputCrop :
378591a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                        OMX_IndexConfigCommonInputCrop),
3786e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &rect, sizeof(rect)) != OK) {
3787e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nLeft = 0;
3788e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nTop = 0;
3789e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nWidth = videoDef->nFrameWidth;
3790e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nHeight = videoDef->nFrameHeight;
3791e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    }
379231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3793777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (rect.nLeft < 0 ||
3794777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        rect.nTop < 0 ||
3795777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        rect.nLeft + rect.nWidth > videoDef->nFrameWidth ||
3796777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        rect.nTop + rect.nHeight > videoDef->nFrameHeight) {
3797777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        ALOGE("Wrong cropped rect (%d, %d) - (%u, %u) vs. frame (%u, %u)",
3798777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                rect.nLeft, rect.nTop,
3799777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                rect.nLeft + rect.nWidth, rect.nTop + rect.nHeight,
3800777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                videoDef->nFrameWidth, videoDef->nFrameHeight);
3801777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return BAD_VALUE;
3802777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
3803e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3804e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setRect(
3805577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            "crop",
3806577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nLeft,
3807577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nTop,
3808e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                            rect.nLeft + rect.nWidth - 1,
3809e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                            rect.nTop + rect.nHeight - 1);
3810e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3811e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3812e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
38134730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
38144730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP8:
38154730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP9:
38164730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                {
38174730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
38184730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    InitOMXParams(&vp8type);
38194730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    vp8type.nPortIndex = kPortIndexOutput;
38204730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    status_t err = mOMX->getParameter(
38214730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            mNode,
38224730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
38234730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            &vp8type,
38244730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            sizeof(vp8type));
38254730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
38264730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    if (err == OK) {
38274730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        AString tsSchema = "none";
38284730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        if (vp8type.eTemporalPattern
38294730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                == OMX_VIDEO_VPXTemporalLayerPatternWebRTC) {
38304730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            switch (vp8type.nTemporalLayerCount) {
38314730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 1:
38324730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
38334730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.1-layer";
38344730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
38354730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
38364730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 2:
38374730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
38384730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.2-layer";
38394730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
38404730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
38414730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 3:
38424730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
38434730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.3-layer";
38444730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
38454730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
38464730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                default:
38474730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
38484730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
38494730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
38504730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            }
38514730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        }
38524730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        notify->setString("ts-schema", tsSchema);
38534730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    }
38544730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    // Fall through to set up mime.
38554730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                }
38564730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
3857e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                default:
3858e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3859777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (mIsEncoder ^ (portIndex == kPortIndexOutput)) {
3860777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        // should be CodingUnused
3861777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        ALOGE("Raw port video compression format is %s(%d)",
3862777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                asString(videoDef->eCompressionFormat),
3863777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                videoDef->eCompressionFormat);
3864777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return BAD_VALUE;
3865777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
3866e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    AString mime;
3867e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    if (GetMimeTypeForVideoCoding(
3868e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        videoDef->eCompressionFormat, &mime) != OK) {
3869e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", "application/octet-stream");
3870e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    } else {
3871e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", mime.c_str());
3872e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    }
3873e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3874e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
387531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            }
3876e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("width", videoDef->nFrameWidth);
3877e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("height", videoDef->nFrameHeight);
38785a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            ALOGV("[%s] %s format is %s", mComponentName.c_str(),
38795a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                    portIndex == kPortIndexInput ? "input" : "output",
38805a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                    notify->debugString().c_str());
38815a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
388231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
388331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
388431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
388531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainAudio:
388631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
388731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
388831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
388997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            switch ((int)audioDef->eEncoding) {
3890e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingPCM:
3891e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3892e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_PCMMODETYPE params;
3893e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3894e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3895e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3896777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
3897777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, OMX_IndexParamAudioPcm, &params, sizeof(params));
3898777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
3899777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
3900777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
390114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
3902777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (params.nChannels <= 0
3903777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            || (params.nChannels != 1 && !params.bInterleaved)
3904777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            || params.nBitPerSample != 16u
3905777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            || params.eNumData != OMX_NumericalDataSigned
3906777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            || params.ePCMMode != OMX_AUDIO_PCMModeLinear) {
3907777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        ALOGE("unsupported PCM port: %u channels%s, %u-bit, %s(%d), %s(%d) mode ",
3908777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                params.nChannels,
3909777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                params.bInterleaved ? " interleaved" : "",
3910777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                params.nBitPerSample,
3911777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                asString(params.eNumData), params.eNumData,
3912777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                asString(params.ePCMMode), params.ePCMMode);
3913777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return FAILED_TRANSACTION;
3914777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
3915e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3916e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
3917e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
3918e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSamplingRate);
3919e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3920e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mChannelMaskPresent) {
3921e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("channel-mask", mChannelMask);
39228b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                    }
3923e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
39248b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                }
39259806555d3930be43e11106281dee354820ac1c88Andreas Huber
3926e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAAC:
3927e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3928e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AACPROFILETYPE params;
3929e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3930e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3931e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3932777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
3933777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, OMX_IndexParamAudioAac, &params, sizeof(params));
3934777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
3935777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
3936777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
3937e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3938e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
3939e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
3940e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
3941e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
3942e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
3943e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3944e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAMR:
3945e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3946e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AMRTYPE params;
3947e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3948e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
39499806555d3930be43e11106281dee354820ac1c88Andreas Huber
3950777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
3951777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, OMX_IndexParamAudioAmr, &params, sizeof(params));
3952777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
3953777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
3954777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
3955e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3956e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", 1);
3957e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) {
3958e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
3959e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_WB);
3960e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3961e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 16000);
3962e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    } else {
3963e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
3964e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
3965e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3966e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 8000);
3967e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
3968e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
3969e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
3970e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3971e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingFLAC:
3972e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3973e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_FLACTYPE params;
3974e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3975e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3976e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3977777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
3978777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, OMX_IndexParamAudioFlac, &params, sizeof(params));
3979777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
3980777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
3981777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
3982e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3983e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC);
3984e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
3985e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
3986e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
3987e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
3988e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3989e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingMP3:
3990e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3991e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_MP3TYPE params;
3992e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
3993e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3994e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3995777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
3996777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, OMX_IndexParamAudioMp3, &params, sizeof(params));
3997777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
3998777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
3999777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4000e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4001e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MPEG);
4002e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
4003e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
4004e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
4005e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
4006e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4007e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingVORBIS:
4008e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
4009e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_VORBISTYPE params;
4010e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
4011e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
4012e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4013777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4014777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, OMX_IndexParamAudioVorbis, &params, sizeof(params));
4015777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4016777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4017777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4018e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4019e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_VORBIS);
4020e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
4021e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
4022e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
4023e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
4024e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
402597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                case OMX_AUDIO_CodingAndroidAC3:
402697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                {
402797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    OMX_AUDIO_PARAM_ANDROID_AC3TYPE params;
402897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    InitOMXParams(&params);
4029e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
403097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
4031777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4032777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
4033777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            &params, sizeof(params));
4034777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4035777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4036777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
403797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
403897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AC3);
403997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("channel-count", params.nChannels);
404097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("sample-rate", params.nSampleRate);
404197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    break;
404297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                }
4043e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
40448a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                case OMX_AUDIO_CodingAndroidEAC3:
40458a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                {
40468a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    OMX_AUDIO_PARAM_ANDROID_EAC3TYPE params;
40478a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    InitOMXParams(&params);
40488a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    params.nPortIndex = portIndex;
40498a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
4050777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4051777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
4052777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            &params, sizeof(params));
4053777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4054777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4055777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
40568a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
40578a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_EAC3);
40588a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setInt32("channel-count", params.nChannels);
40598a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setInt32("sample-rate", params.nSampleRate);
40608a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    break;
40618a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                }
40628a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
40638c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                case OMX_AUDIO_CodingAndroidOPUS:
40648c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                {
40658c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    OMX_AUDIO_PARAM_ANDROID_OPUSTYPE params;
40668c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    InitOMXParams(&params);
40678c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    params.nPortIndex = portIndex;
40688c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
4069777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4070777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus,
4071777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            &params, sizeof(params));
4072777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4073777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4074777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
40758c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
40768c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_OPUS);
40778c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("channel-count", params.nChannels);
40788c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("sample-rate", params.nSampleRate);
40798c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    break;
40808c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                }
40818c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
408210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                case OMX_AUDIO_CodingG711:
408310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                {
408410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    OMX_AUDIO_PARAM_PCMMODETYPE params;
408510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    InitOMXParams(&params);
408610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    params.nPortIndex = portIndex;
408710d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
4088777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4089777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioPcm, &params, sizeof(params));
4090777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4091777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4092777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
409310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
409410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    const char *mime = NULL;
409510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    if (params.ePCMMode == OMX_AUDIO_PCMModeMULaw) {
409610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_G711_MLAW;
409710d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    } else if (params.ePCMMode == OMX_AUDIO_PCMModeALaw) {
409810d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_G711_ALAW;
409910d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    } else { // params.ePCMMode == OMX_AUDIO_PCMModeLinear
410010d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_RAW;
410110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    }
410210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setString("mime", mime);
410310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setInt32("channel-count", params.nChannels);
410410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setInt32("sample-rate", params.nSamplingRate);
410510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    break;
410610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                }
410741d3f579d2c166984958263533284209b90c87d5Marco Nelissen
410841d3f579d2c166984958263533284209b90c87d5Marco Nelissen                case OMX_AUDIO_CodingGSMFR:
410941d3f579d2c166984958263533284209b90c87d5Marco Nelissen                {
411041d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    OMX_AUDIO_PARAM_MP3TYPE params;
411141d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    InitOMXParams(&params);
411241d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    params.nPortIndex = portIndex;
411341d3f579d2c166984958263533284209b90c87d5Marco Nelissen
4114777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4115777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                mNode, OMX_IndexParamAudioPcm, &params, sizeof(params));
4116777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4117777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4118777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
411941d3f579d2c166984958263533284209b90c87d5Marco Nelissen
412041d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MSGSM);
412141d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    notify->setInt32("channel-count", params.nChannels);
412241d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    notify->setInt32("sample-rate", params.nSampleRate);
412341d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    break;
412410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                }
412510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
4126e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                default:
4127777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGE("Unsupported audio coding: %s(%d)\n",
4128777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            asString(audioDef->eEncoding), audioDef->eEncoding);
4129777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return BAD_TYPE;
4130e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
413131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
413231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
413331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
413431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        default:
4135777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("Unsupported domain: %s(%d)", asString(def.eDomain), def.eDomain);
4136777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return BAD_TYPE;
413731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    }
413831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4139e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    return OK;
4140e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar}
4141e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4142e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarvoid ACodec::sendFormatChange(const sp<AMessage> &reply) {
41434e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    sp<AMessage> notify = mBaseOutputFormat->dup();
4144e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    notify->setInt32("what", kWhatOutputFormatChanged);
4145e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4146777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (getPortFormat(kPortIndexOutput, notify) != OK) {
4147777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("[%s] Failed to get port format to send format change", mComponentName.c_str());
4148777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return;
4149777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
4150e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4151e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    AString mime;
4152e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK(notify->findString("mime", &mime));
4153e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4154e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    int32_t left, top, right, bottom;
4155e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if (mime == MEDIA_MIMETYPE_VIDEO_RAW &&
4156e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        mNativeWindow != NULL &&
4157e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->findRect("crop", &left, &top, &right, &bottom)) {
4158e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        // notify renderer of the crop change
4159e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        // NOTE: native window uses extended right-bottom coordinate
4160e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        reply->setRect("crop", left, top, right + 1, bottom + 1);
4161e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    } else if (mime == MEDIA_MIMETYPE_AUDIO_RAW &&
4162e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar               (mEncoderDelay || mEncoderPadding)) {
4163e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        int32_t channelCount;
4164e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        CHECK(notify->findInt32("channel-count", &channelCount));
4165e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        size_t frameSize = channelCount * sizeof(int16_t);
4166e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        if (mSkipCutBuffer != NULL) {
4167e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            size_t prevbufsize = mSkipCutBuffer->size();
4168e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            if (prevbufsize != 0) {
4169ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                ALOGW("Replacing SkipCutBuffer holding %zu bytes", prevbufsize);
4170e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            }
4171e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        }
4172e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        mSkipCutBuffer = new SkipCutBuffer(
4173e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                mEncoderDelay * frameSize,
4174e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                mEncoderPadding * frameSize);
4175e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
4176e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
417731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->post();
417831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
417931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mSentFormat = true;
418031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber}
418131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
41825778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
4183cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    sp<AMessage> notify = mNotify->dup();
4184d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatError);
4185251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    ALOGE("signalError(omxError %#x, internalError %d)", error, internalError);
4186251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
4187251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (internalError == UNKNOWN_ERROR) { // find better error code
4188251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        const status_t omxStatus = statusFromOMXError(error);
4189251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        if (omxStatus != 0) {
4190251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            internalError = omxStatus;
4191251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        } else {
4192251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            ALOGW("Invalid OMX error %#x", error);
4193251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        }
4194251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
41955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("err", internalError);
4196251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    notify->setInt32("actionCode", ACTION_CODE_FATAL); // could translate from OMX error.
4197cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->post();
4198cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber}
4199cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber
4200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4202eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberACodec::PortDescription::PortDescription() {
4203eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
4204eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4205496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t ACodec::requestIDRFrame() {
4206496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    if (!mIsEncoder) {
4207496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        return ERROR_UNSUPPORTED;
4208496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    }
4209496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4210496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    OMX_CONFIG_INTRAREFRESHVOPTYPE params;
4211496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    InitOMXParams(&params);
4212496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4213496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.nPortIndex = kPortIndexOutput;
4214496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.IntraRefreshVOP = OMX_TRUE;
4215496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4216496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    return mOMX->setConfig(
4217496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            mNode,
4218496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            OMX_IndexConfigVideoIntraVOPRefresh,
4219496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            &params,
4220496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            sizeof(params));
4221496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
4222496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4223eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubervoid ACodec::PortDescription::addBuffer(
4224eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        IOMX::buffer_id id, const sp<ABuffer> &buffer) {
4225eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBufferIDs.push_back(id);
4226eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBuffers.push_back(buffer);
4227eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
4228eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4229eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersize_t ACodec::PortDescription::countBuffers() {
4230eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.size();
4231eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
4232eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4233eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberIOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const {
4234eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.itemAt(index);
4235eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
4236eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4237eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const {
4238eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBuffers.itemAt(index);
4239eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
4240eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4241eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber////////////////////////////////////////////////////////////////////////////////
4242eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4243f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
4244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : AState(parentState),
4245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mCodec(codec) {
4246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4248ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas HuberACodec::BaseState::PortMode ACodec::BaseState::getPortMode(
4249ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
4250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return KEEP_BUFFERS;
4251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4253f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
4254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatInputBufferFilled:
4256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onInputBufferFilled(msg);
4258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatOutputBufferDrained:
4262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onOutputBufferDrained(msg);
4264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatOMXMessage:
4268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXMessage(msg);
4270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
42721dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        case ACodec::kWhatSetSurface:
42731dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        {
42741dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            sp<AReplyToken> replyID;
42751dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            CHECK(msg->senderAwaitsResponse(&replyID));
42761dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
42771dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            sp<RefBase> obj;
42781dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            CHECK(msg->findObject("surface", &obj));
42791dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
4280011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            status_t err =
4281011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                ADebug::isExperimentEnabled("legacy-setsurface") ? BAD_VALUE :
4282011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                        mCodec->handleSetSurface(static_cast<Surface *>(obj.get()));
42831dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
42841dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            sp<AMessage> response = new AMessage;
42851dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            response->setInt32("err", err);
42861dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            response->postReply(replyID);
42871dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            break;
42881dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
42891dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
42907cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
4291d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        case ACodec::kWhatUsePersistentInputSurface:
42927cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
42937cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
4294251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            // This may result in an app illegal state exception.
42957cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            ALOGE("Message 0x%x was not handled", msg->what());
42967cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
42977cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            return true;
42987cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
42997cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4300ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        case ACodec::kWhatOMXDied:
4301ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        {
4302251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            // This will result in kFlagSawMediaServerDie handling in MediaCodec.
4303ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            ALOGE("OMX/mediaserver died, signalling error!");
4304ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT);
4305ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            break;
4306ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        }
4307ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
430830358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        case ACodec::kWhatReleaseCodecInstance:
430930358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        {
431030358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            ALOGI("[%s] forcing the release of codec",
431130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar                    mCodec->mComponentName.c_str());
431230358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            status_t err = mCodec->mOMX->freeNode(mCodec->mNode);
431330358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            ALOGE_IF("[%s] failed to release codec instance: err=%d",
431430358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar                       mCodec->mComponentName.c_str(), err);
431530358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            sp<AMessage> notify = mCodec->mNotify->dup();
431630358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
431730358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            notify->post();
431830358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            break;
431930358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        }
432030358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar
4321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
4323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4328f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
4329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t type;
4330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findInt32("type", &type));
4331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
43325e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // there is a possibility that this is an outstanding message for a
43335e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // codec that we have already destroyed
4334ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    if (mCodec->mNode == 0) {
43355e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar        ALOGI("ignoring message as already freed component: %s",
43365e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar                msg->debugString().c_str());
43375e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar        return true;
43385e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    }
43395e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar
4340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::node_id nodeID;
4341609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("node", (int32_t*)&nodeID));
4342777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (nodeID != mCodec->mNode) {
4343777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("Unexpected message for nodeID: %u, should have been %u", nodeID, mCodec->mNode);
4344777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return false;
4345777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
4346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (type) {
4348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EVENT:
4349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t event, data1, data2;
4351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("event", &event));
4352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data1", &data1));
4353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data2", &data2));
4354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
43550af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            if (event == OMX_EventCmdComplete
43560af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data1 == OMX_CommandFlush
43570af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data2 == (int32_t)OMX_ALL) {
43580af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // Use of this notification is not consistent across
43590af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // implementations. We'll drop this notification and rely
43600af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // on flush-complete notifications on the individual port
43610af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // indices instead.
43620af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
43630af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                return true;
43640af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            }
43650af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
4366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEvent(
4367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_EVENTTYPE>(event),
4368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data1),
4369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data2));
4370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EMPTY_BUFFER_DONE:
4373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
4375609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
4376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEmptyBufferDone(bufferID);
4378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::FILL_BUFFER_DONE:
4381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
4383609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
4384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t rangeOffset, rangeLength, flags;
4386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs;
4387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_offset", &rangeOffset));
4389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_length", &rangeLength));
4390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("flags", &flags));
4391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt64("timestamp", &timeUs));
4392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXFillBufferDone(
4394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    bufferID,
4395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (size_t)rangeOffset, (size_t)rangeLength,
4396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (OMX_U32)flags,
4397784e24e386b088c05d653ab482f2e95cb53e3d01Andy Hung                    timeUs);
4398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4401777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("Unexpected message type: %d", type);
4402777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return false;
4403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4406f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEvent(
4407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (event != OMX_EventError) {
4409ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        ALOGV("[%s] EVENT(%d, 0x%08x, 0x%08x)",
4410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mCodec->mComponentName.c_str(), event, data1, data2);
4411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return false;
4413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4415ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGE("[%s] ERROR(0x%08x)", mCodec->mComponentName.c_str(), data1);
4416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4417251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // verify OMX component sends back an error we expect.
4418251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    OMX_ERRORTYPE omxError = (OMX_ERRORTYPE)data1;
4419251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (!isOMXError(omxError)) {
4420251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        ALOGW("Invalid OMX error %#x", omxError);
4421251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        omxError = OMX_ErrorUndefined;
4422251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
4423251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    mCodec->signalError(omxError);
4424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4428f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID) {
4429ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGV("[%s] onOMXEmptyBufferDone %u",
4430349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber         mCodec->mComponentName.c_str(), bufferID);
4431349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
4433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexInput, bufferID);
4434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
4436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
4437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
443896e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // We're in "store-metadata-in-buffers" mode, the underlying
443996e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // OMX component had access to data that's implicitly refcounted
444096e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // by this "MediaBuffer" object. Now that the OMX component has
444196e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // told us that it's done with the input buffer, we can decrement
444296e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // the mediaBuffer's reference count.
444396e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    info->mData->setMediaBufferBase(NULL);
4444d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
4446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            postFillThisBuffer(info);
4453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4455777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        case FREE_BUFFERS:
4456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4457777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("SHOULD NOT REACH HERE: cannot free empty output buffers");
4458777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return false;
4459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4464f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
4465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
4466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
4467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
4470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
4472d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatFillThisBuffer);
4473609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    notify->setInt32("buffer-id", info->mBufferID);
4474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mData->meta()->clear();
44762d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    notify->setBuffer("buffer", info->mData);
4477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
44781d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec);
4479609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    reply->setInt32("buffer-id", info->mBufferID);
4480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setMessage("reply", reply);
4482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->post();
4484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
4486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4488f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
4489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
4490609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
44912d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    sp<ABuffer> buffer;
4492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t err = OK;
44935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool eos = false;
4494a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar    PortMode mode = getPortMode(kPortIndexInput);
44955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
44962d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    if (!msg->findBuffer("buffer", &buffer)) {
4497a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar        /* these are unfilled buffers returned by client */
4498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findInt32("err", &err));
4499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
45007fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        if (err == OK) {
45017fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            /* buffers with no errors are returned on MediaCodec.flush */
45027fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            mode = KEEP_BUFFERS;
45037fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        } else {
45047fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            ALOGV("[%s] saw error %d instead of an input buffer",
45057fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                 mCodec->mComponentName.c_str(), err);
45067fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            eos = true;
45077fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        }
45083831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
45092d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber        buffer.clear();
4510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
45125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
45135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
45145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
45155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = ERROR_END_OF_STREAM;
45165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
45175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
4519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_UPSTREAM);
4520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
4522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
45265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (eos) {
4527dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (!mCodec->mPortEOS[kPortIndexInput]) {
4528dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
4529dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mInputEOSResult = err;
4530dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
4531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
45375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
4538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int64_t timeUs;
4539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
4540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
4542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t isCSD;
4544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
4545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
4546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
4547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
45485778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (eos) {
45495778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    flags |= OMX_BUFFERFLAG_EOS;
45505778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
45515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer != info->mData) {
4553ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] Needs to copy input data for buffer %u. (%p != %p)",
4554d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(),
4555d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         bufferID,
4556d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         buffer.get(), info->mData.get());
4557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    CHECK_LE(buffer->size(), info->mData->capacity());
4559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    memcpy(info->mData->data(), buffer->data(), buffer->size());
4560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
4561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4562078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
4563ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] calling emptyBuffer %u w/ codec specific data",
4564078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID);
45655778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else if (flags & OMX_BUFFERFLAG_EOS) {
4566ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] calling emptyBuffer %u w/ EOS",
45675778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str(), bufferID);
4568078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                } else {
4569d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
4570ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGI("[%s] calling emptyBuffer %u w/ time %lld us",
4571ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                         mCodec->mComponentName.c_str(), bufferID, (long long)timeUs);
4572d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#else
4573ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] calling emptyBuffer %u w/ time %lld us",
4574ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                         mCodec->mComponentName.c_str(), bufferID, (long long)timeUs);
4575d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
4576078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                }
4577349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4578d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
4579d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ACodec::BufferStats stats;
4580d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
4581d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mFillBufferDoneTimeUs = -1ll;
4582d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mCodec->mBufferStats.add(timeUs, stats);
4583d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
4584d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4585054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                if (mCodec->mStoreMetaDataInOutputBuffers) {
4586054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    // try to submit an output buffer for each input buffer
4587054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    PortMode outputMode = getPortMode(kPortIndexOutput);
4588054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4589054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    ALOGV("MetaDataBuffersToSubmit=%u portMode=%s",
4590054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            mCodec->mMetaDataBuffersToSubmit,
4591054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            (outputMode == FREE_BUFFERS ? "FREE" :
4592054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                             outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
4593054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    if (outputMode == RESUBMIT_BUFFERS) {
4594e53350373ac516257b4f8956ff1e3f1ac48f607eLajos Molnar                        mCodec->submitOutputMetaDataBuffer();
4595054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    }
4596054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                }
4597054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
4599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
4600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
4601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
4602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            buffer->size(),
4603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            flags,
4604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            timeUs),
4605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
46095778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (!eos) {
46105778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    getMoreInputDataIfPossible();
46115778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
46125778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] Signalled EOS on the input port",
46135778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str());
46145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
46155778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
46165778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mInputEOSResult = err;
46175778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
4618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
4619dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (err != ERROR_END_OF_STREAM) {
46203856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port "
4621dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         "due to error %d",
4622dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str(), err);
4623dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                } else {
46243856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port",
4625dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str());
4626dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
4627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4628ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                ALOGV("[%s] calling emptyBuffer %u signalling EOS",
4629349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                     mCodec->mComponentName.c_str(), bufferID);
4630349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
4632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
4633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
4634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
4635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
4636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_BUFFERFLAG_EOS,
4637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0),
4638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexInput] = true;
4643dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                mCodec->mInputEOSResult = err;
4644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4647625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih
4648777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        case FREE_BUFFERS:
4649777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            break;
4650777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim
4651625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih        default:
4652777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("invalid port mode: %d", mode);
4653625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih            break;
4654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4657f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::getMoreInputDataIfPossible() {
4658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
4659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
4660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *eligible = NULL;
4663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
4665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
4666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
4668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
4669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // There's already a "read" pending.
4670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
4671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
4673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_US) {
4675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            eligible = info;
4676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (eligible == NULL) {
4680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
4681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(eligible);
4684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4686f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXFillBufferDone(
4687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferID,
4688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        size_t rangeOffset, size_t rangeLength,
4689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 flags,
4690784e24e386b088c05d653ab482f2e95cb53e3d01Andy Hung        int64_t timeUs) {
4691609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] onOMXFillBufferDone %u time %" PRId64 " us, flags = 0x%08x",
46925778822d86b0337407514b9372562b86edfa91cdAndreas Huber         mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
4693349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
4695d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4696d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
4697d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    index = mCodec->mBufferStats.indexOfKey(timeUs);
4698d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (index >= 0) {
4699d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
4700d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
4701d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4702d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ALOGI("frame PTS %lld: %lld",
4703d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                timeUs,
4704d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
4705d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4706d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mCodec->mBufferStats.removeItemsAt(index);
4707d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats = NULL;
4708d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
4709d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
4710d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
4712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
4713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
4715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4716054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mDequeuedAt = ++mCodec->mDequeueCounter;
4717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
4718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
4720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4727a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            if (rangeLength == 0 && (!(flags & OMX_BUFFERFLAG_EOS)
4728a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                    || mCodec->mPortEOS[kPortIndexOutput])) {
4729609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                ALOGV("[%s] calling fillBuffer %u",
47305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                     mCodec->mComponentName.c_str(), info->mBufferID);
4731349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
47325778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK_EQ(mCodec->mOMX->fillBuffer(
47335778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mCodec->mNode, info->mBufferID),
47345778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         (status_t)OK);
4735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
47365778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
47375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
47385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
473931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4740577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            sp<AMessage> reply =
47411d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar                new AMessage(kWhatOutputBufferDrained, mCodec);
4742577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
47434bdda35319d5f46efea2089b865c8a64816389cdMarco Nelissen            if (!mCodec->mSentFormat && rangeLength > 0) {
4744577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->sendFormatChange(reply);
47455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
4746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4747308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            if (mCodec->mUseMetadataOnEncoderOutput) {
4748308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                native_handle_t* handle =
4749308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        *(native_handle_t**)(info->mData->data() + 4);
4750308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setPointer("handle", handle);
4751308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeOffset", rangeOffset);
4752308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeLength", rangeLength);
4753308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            } else {
4754308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->setRange(rangeOffset, rangeLength);
4755308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            }
4756496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#if 0
475721ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen            if (mCodec->mNativeWindow == NULL) {
4758496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                if (IsIDR(info->mData)) {
4759496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                    ALOGI("IDR frame");
4760496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                }
47615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
476221ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen#endif
4763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
47648b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            if (mCodec->mSkipCutBuffer != NULL) {
47658b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                mCodec->mSkipCutBuffer->submit(info->mData);
47668b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            }
47675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mData->meta()->setInt64("timeUs", timeUs);
4768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
47695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4770d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatDrainThisBuffer);
4771609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            notify->setInt32("buffer-id", info->mBufferID);
47722d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            notify->setBuffer("buffer", info->mData);
47735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("flags", flags);
4774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4775609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            reply->setInt32("buffer-id", info->mBufferID);
4776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
47775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setMessage("reply", reply);
4778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
47795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->post();
47805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
47815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
4782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (flags & OMX_BUFFERFLAG_EOS) {
47845778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
47855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                sp<AMessage> notify = mCodec->mNotify->dup();
4787d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar                notify->setInt32("what", CodecBase::kWhatEOS);
4788dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                notify->setInt32("err", mCodec->mInputEOSResult);
4789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->post();
4790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexOutput] = true;
4792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4796777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        case FREE_BUFFERS:
4797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
4798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
4799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4800777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim
4801777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        default:
4802777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("Invalid port mode: %d", mode);
4803777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return false;
4804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4809f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
4810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
4811609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
4812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
4813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
4814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
4815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM);
4816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4817577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    android_native_rect_t crop;
4818777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (msg->findRect("crop", &crop.left, &crop.top, &crop.right, &crop.bottom)) {
4819777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        status_t err = native_window_set_crop(mCodec->mNativeWindow.get(), &crop);
4820777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGW_IF(err != NO_ERROR, "failed to set crop: %d", err);
4821577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    }
4822577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
4823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t render;
4824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mNativeWindow != NULL
48256aade6058521b0dbd35a9a4620f4d04f02f90444Marco Nelissen            && msg->findInt32("render", &render) && render != 0
482679ee2399b67c7a11042c5904dc1309712a76f8cbJianzheng Zhou            && info->mData != NULL && info->mData->size() != 0) {
48276fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        ATRACE_NAME("render");
4828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The client wants this buffer to be rendered.
4829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4830fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        int64_t timestampNs = 0;
4831fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        if (!msg->findInt64("timestampNs", &timestampNs)) {
4832fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // TODO: it seems like we should use the timestamp
4833fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // in the (media)buffer as it potentially came from
4834fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // an input surface, but we did not propagate it prior to
4835fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // API 20.  Perhaps check for target SDK version.
4836fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#if 0
4837fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            if (info->mData->meta()->findInt64("timeUs", &timestampNs)) {
483847aea1f7c58f5302b16822f9e7e1763f2af04ef5Lajos Molnar                ALOGV("using buffer PTS of %" PRId64, timestampNs);
4839fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar                timestampNs *= 1000;
4840fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            }
4841fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#endif
4842fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
4843fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
48445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err;
4845fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        err = native_window_set_buffers_timestamp(mCodec->mNativeWindow.get(), timestampNs);
4846fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        if (err != OK) {
4847fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            ALOGW("failed to set buffer timestamp: %d", err);
4848fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
4849fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
48505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if ((err = mCodec->mNativeWindow->queueBuffer(
4851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNativeWindow.get(),
48521e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                    info->mGraphicBuffer.get(), -1)) == OK) {
4853cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
4854cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        } else {
4855251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
4856cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
4857cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        }
4858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
48596fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        if (mCodec->mNativeWindow != NULL &&
48606fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar            (info->mData == NULL || info->mData->size() != 0)) {
48616fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar            ATRACE_NAME("frame-drop");
48626fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        }
4863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_US;
4864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
4867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
4872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // We cannot resubmit the buffer we just rendered, dequeue
4875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // the spare instead.
4876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info = mCodec->dequeueBufferFromNativeWindow();
4878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (!mCodec->mPortEOS[kPortIndexOutput]) {
4885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // We cannot resubmit the buffer we just rendered, dequeue
4887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // the spare instead.
4888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info = mCodec->dequeueBufferFromNativeWindow();
4890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
4891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4892c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                if (info != NULL) {
4893609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                    ALOGV("[%s] calling fillBuffer %u",
4894c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                         mCodec->mComponentName.c_str(), info->mBufferID);
4895349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4896c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
4897c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                             (status_t)OK);
4898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4899c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4900c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                }
4901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4905777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        case FREE_BUFFERS:
4906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
4908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
4909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4911777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim
4912777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        default:
4913777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("Invalid port mode: %d", mode);
4914777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return;
4915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4920f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::UninitializedState::UninitializedState(ACodec *codec)
4921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4924c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::UninitializedState::stateEntered() {
4925c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("Now uninitialized");
4926ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4927ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (mDeathNotifier != NULL) {
4928f888020c6e2735624f2b2a30e72aca24e17b8b4dMarco Nelissen        IInterface::asBinder(mCodec->mOMX)->unlinkToDeath(mDeathNotifier);
4929ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
4930ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
4931ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4932ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNativeWindow.clear();
4933ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    mCodec->mNode = 0;
4934ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mOMX.clear();
4935ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mQuirks = 0;
4936ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mFlags = 0;
4937308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    mCodec->mUseMetadataOnEncoderOutput = 0;
4938ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mComponentName.clear();
4939c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4940c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4941f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
4942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatSetup:
4946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onSetup(msg);
4948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
49535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case ACodec::kWhatAllocateComponent:
49545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
49555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            onAllocateComponent(msg);
49565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            handled = true;
49575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
49585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
49595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatShutdown:
4961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4962c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
4963c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
4964c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
496554b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            ALOGW_IF(keepComponentAllocated,
496654b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar                     "cannot keep component allocated on shutdown in Uninitialized state");
4967c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4969d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
4970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
4971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4973c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
4974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatFlush:
4977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4979d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
4980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
4981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4983c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
4984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
498630358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        case ACodec::kWhatReleaseCodecInstance:
498730358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        {
498830358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            // nothing to do, as we have already signaled shutdown
498930358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            handled = true;
499030358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            break;
499130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        }
499230358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar
4993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
4995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5000f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::UninitializedState::onSetup(
5001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
5002c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (onAllocateComponent(msg)
5003c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            && mCodec->mLoadedState->onConfigureComponent(msg)) {
5004c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mLoadedState->onStart();
5005c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
50065778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
50075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5008c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
50095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onAllocateComponent");
50105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5011ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    CHECK(mCodec->mNode == 0);
50125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMXClient client;
501448a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung    if (client.connect() != OK) {
501548a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung        mCodec->signalError(OMX_ErrorUndefined, NO_INIT);
501648a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung        return false;
501748a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung    }
5018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<IOMX> omx = client.interface();
5020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
50211d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec);
5022ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
5023ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mDeathNotifier = new DeathNotifier(notify);
5024f888020c6e2735624f2b2a30e72aca24e17b8b4dMarco Nelissen    if (IInterface::asBinder(omx)->linkToDeath(mDeathNotifier) != OK) {
5025ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // This was a local binder, if it dies so do we, we won't care
5026ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // about any notifications in the afterlife.
5027ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
5028ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
5029ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
5030e671207115fac3914134c61b336d5fa0242c68caAndreas Huber    Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs;
50315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    AString mime;
5033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
50345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString componentName;
5035d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint32_t quirks = 0;
50367791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen    int32_t encoder = false;
50375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findString("componentName", &componentName)) {
5038e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        ssize_t index = matchingCodecs.add();
5039e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        OMXCodec::CodecNameAndQuirks *entry = &matchingCodecs.editItemAt(index);
5040e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        entry->mName = String8(componentName.c_str());
5041afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
5042e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        if (!OMXCodec::findCodecQuirks(
5043e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                    componentName.c_str(), &entry->mQuirks)) {
5044e671207115fac3914134c61b336d5fa0242c68caAndreas Huber            entry->mQuirks = 0;
5045afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
50465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
50475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(msg->findString("mime", &mime));
50485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
50495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("encoder", &encoder)) {
50505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder = false;
50515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
50525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
50535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMXCodec::findMatchingCodecs(
50545778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mime.c_str(),
50555778822d86b0337407514b9372562b86edfa91cdAndreas Huber                encoder, // createEncoder
50565778822d86b0337407514b9372562b86edfa91cdAndreas Huber                NULL,  // matchComponentName
50575778822d86b0337407514b9372562b86edfa91cdAndreas Huber                0,     // flags
5058e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                &matchingCodecs);
50595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
50601065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
50611065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    sp<CodecObserver> observer = new CodecObserver;
5062ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    IOMX::node_id node = 0;
50631065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
50649f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu    status_t err = OMX_ErrorComponentNotFound;
50651065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
50661065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            ++matchIndex) {
5067e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        componentName = matchingCodecs.itemAt(matchIndex).mName.string();
5068e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        quirks = matchingCodecs.itemAt(matchIndex).mQuirks;
5069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5070da153975581fb3161a30452348a5b26ee72d9255Elliott Hughes        pid_t tid = gettid();
5071078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        int prevPriority = androidGetThreadPriority(tid);
5072078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
50739f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu        err = omx->allocateNode(componentName.c_str(), observer, &node);
5074078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, prevPriority);
5075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
50761065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        if (err == OK) {
50771065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            break;
50787a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He        } else {
50797a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He            ALOGW("Allocating component '%s' failed, try next one.", componentName.c_str());
50801065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
50811065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
5082ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        node = 0;
50831065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    }
50841065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
5085ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    if (node == 0) {
50865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!mime.empty()) {
50879f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu            ALOGE("Unable to instantiate a %scoder for type '%s' with err %#x.",
50889f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu                    encoder ? "en" : "de", mime.c_str(), err);
50895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
50909f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu            ALOGE("Unable to instantiate codec '%s' with err %#x.", componentName.c_str(), err);
50915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
5092c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
509352e88b2986536e83a7a6da63461556b8734a85f3Ronghua Wu        mCodec->signalError((OMX_ERRORTYPE)err, makeNoSideEffectStatus(err));
5094c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
5095c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
5096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
50971d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    notify = new AMessage(kWhatOMXMessage, mCodec);
5098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    observer->setNotificationMessage(notify);
5099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mComponentName = componentName;
5101ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    mCodec->mFlags = 0;
5102ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
5103ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (componentName.endsWith(".secure")) {
5104ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        mCodec->mFlags |= kFlagIsSecure;
51051713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        mCodec->mFlags |= kFlagIsGrallocUsageProtected;
51060167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
5107ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
5108ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
5109afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mCodec->mQuirks = quirks;
5110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mOMX = omx;
5111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mNode = node;
5112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
51135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
51145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
5115d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatComponentAllocated);
51165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setString("componentName", mCodec->mComponentName.c_str());
51175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
51185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5119c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5120c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mCodec->changeState(mCodec->mLoadedState);
5121c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5122c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
51235778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
51245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5125c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
5126c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5127c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas HuberACodec::LoadedState::LoadedState(ACodec *codec)
5128c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    : BaseState(codec) {
5129c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
5130c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5131c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::stateEntered() {
5132c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
5133c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5134f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mPortEOS[kPortIndexInput] =
5135f6f38287b97ec69b169387add6458f859b770e65Andreas Huber        mCodec->mPortEOS[kPortIndexOutput] = false;
5136f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
5137f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mInputEOSResult = OK;
5138f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
5139054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mDequeueCounter = 0;
5140054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mMetaDataBuffersToSubmit = 0;
5141a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    mCodec->mRepeatFrameDelayUs = -1ll;
5142e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mInputFormat.clear();
5143e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mOutputFormat.clear();
51444e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    mCodec->mBaseOutputFormat.clear();
5145054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5146c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (mCodec->mShutdownInProgress) {
5147c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
5148c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5149c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mShutdownInProgress = false;
5150c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mKeepComponentAllocated = false;
5151c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5152c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        onShutdown(keepComponentAllocated);
5153c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
515454b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    mCodec->mExplicitShutdown = false;
5155f393c33e65ae51a7cf168b4e15771b152f996b32Wei Jia
5156f393c33e65ae51a7cf168b4e15771b152f996b32Wei Jia    mCodec->processDeferredMessages();
5157c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
5158c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5159c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
5160c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (!keepComponentAllocated) {
5161c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK);
5162c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5163c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->changeState(mCodec->mUninitializedState);
5164c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
5165c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
516654b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    if (mCodec->mExplicitShutdown) {
516754b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        sp<AMessage> notify = mCodec->mNotify->dup();
5168d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
516954b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        notify->post();
517054b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        mCodec->mExplicitShutdown = false;
517154b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    }
5172c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
5173c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5174c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
5175c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool handled = false;
5176c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5177c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    switch (msg->what()) {
5178c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatConfigureComponent:
5179c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
5180c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onConfigureComponent(msg);
5181c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
5182c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
5183c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
5184c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
51857cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
51867cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
51877cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            onCreateInputSurface(msg);
51887cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
51897cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
51907cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
51917cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
5192d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        case ACodec::kWhatUsePersistentInputSurface:
5193d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        {
5194d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            onUsePersistentInputSurface(msg);
5195d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            handled = true;
5196d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            break;
5197d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        }
5198d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5199c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatStart:
5200c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
5201c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onStart();
5202c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
5203c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
5204c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
5205c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5206c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatShutdown:
5207c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
5208c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
5209c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
5210c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
5211c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
521254b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
5213c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onShutdown(keepComponentAllocated);
5214c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5215c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
5216c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
5217c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
5218c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5219c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatFlush:
5220c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
5221c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
5222d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
5223c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->post();
5224c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5225c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
5226c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
5227c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
5228c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5229c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        default:
5230c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            return BaseState::onMessageReceived(msg);
5231c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
5232c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5233c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return handled;
5234c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
5235c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5236c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onConfigureComponent(
52375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg) {
52385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onConfigureComponent");
52395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5240ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    CHECK(mCodec->mNode != 0);
52415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
52425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString mime;
52435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findString("mime", &mime));
52445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
52455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mCodec->configureCodec(mime.c_str(), msg);
52465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
52475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
5248c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        ALOGE("[%s] configureCodec returning error %d",
5249c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber              mCodec->mComponentName.c_str(), err);
5250c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber
5251251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5252c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
52535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
52555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
52565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
5257d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatComponentConfigured);
5258e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("input-format", mCodec->mInputFormat);
5259e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("output-format", mCodec->mOutputFormat);
52605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
52615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5262c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5263c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
52645778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
52655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5266d291c222357303b9611cab89d0c3b047584ef377Chong Zhangstatus_t ACodec::LoadedState::setupInputSurface() {
5267d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    status_t err = OK;
5268a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
5269d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mRepeatFrameDelayUs > 0ll) {
5270a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        err = mCodec->mOMX->setInternalOption(
5271a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                mCodec->mNode,
5272a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                kPortIndexInput,
5273a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY,
5274a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                &mCodec->mRepeatFrameDelayUs,
5275a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                sizeof(mCodec->mRepeatFrameDelayUs));
5276a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
5277a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (err != OK) {
5278a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            ALOGE("[%s] Unable to configure option to repeat previous "
5279a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  "frames (err %d)",
5280a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  mCodec->mComponentName.c_str(),
5281a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  err);
5282d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
5283a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
5284a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
5285a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
5286d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mMaxPtsGapUs > 0ll) {
528794ee4b708acfa941581160b267afb79192b1d816Chong Zhang        err = mCodec->mOMX->setInternalOption(
528894ee4b708acfa941581160b267afb79192b1d816Chong Zhang                mCodec->mNode,
528994ee4b708acfa941581160b267afb79192b1d816Chong Zhang                kPortIndexInput,
529094ee4b708acfa941581160b267afb79192b1d816Chong Zhang                IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP,
529194ee4b708acfa941581160b267afb79192b1d816Chong Zhang                &mCodec->mMaxPtsGapUs,
529294ee4b708acfa941581160b267afb79192b1d816Chong Zhang                sizeof(mCodec->mMaxPtsGapUs));
529394ee4b708acfa941581160b267afb79192b1d816Chong Zhang
529494ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (err != OK) {
529594ee4b708acfa941581160b267afb79192b1d816Chong Zhang            ALOGE("[%s] Unable to configure max timestamp gap (err %d)",
529672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    mCodec->mComponentName.c_str(),
529772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    err);
5298d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
52992c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
53002c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
53012c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
5302d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mMaxFps > 0) {
530337b2b389139ed638831e49708c947863eef631efRonghua Wu        err = mCodec->mOMX->setInternalOption(
530437b2b389139ed638831e49708c947863eef631efRonghua Wu                mCodec->mNode,
530537b2b389139ed638831e49708c947863eef631efRonghua Wu                kPortIndexInput,
530637b2b389139ed638831e49708c947863eef631efRonghua Wu                IOMX::INTERNAL_OPTION_MAX_FPS,
530737b2b389139ed638831e49708c947863eef631efRonghua Wu                &mCodec->mMaxFps,
530837b2b389139ed638831e49708c947863eef631efRonghua Wu                sizeof(mCodec->mMaxFps));
530937b2b389139ed638831e49708c947863eef631efRonghua Wu
531037b2b389139ed638831e49708c947863eef631efRonghua Wu        if (err != OK) {
531137b2b389139ed638831e49708c947863eef631efRonghua Wu            ALOGE("[%s] Unable to configure max fps (err %d)",
531237b2b389139ed638831e49708c947863eef631efRonghua Wu                    mCodec->mComponentName.c_str(),
531337b2b389139ed638831e49708c947863eef631efRonghua Wu                    err);
5314d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
531537b2b389139ed638831e49708c947863eef631efRonghua Wu        }
531637b2b389139ed638831e49708c947863eef631efRonghua Wu    }
531737b2b389139ed638831e49708c947863eef631efRonghua Wu
5318d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mTimePerCaptureUs > 0ll
53192c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            && mCodec->mTimePerFrameUs > 0ll) {
53202c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        int64_t timeLapse[2];
53212c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[0] = mCodec->mTimePerFrameUs;
53222c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[1] = mCodec->mTimePerCaptureUs;
53232c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        err = mCodec->mOMX->setInternalOption(
53242c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                mCodec->mNode,
53252c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                kPortIndexInput,
53262c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                IOMX::INTERNAL_OPTION_TIME_LAPSE,
53272c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                &timeLapse[0],
53282c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                sizeof(timeLapse));
53292c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
53302c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (err != OK) {
53312c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            ALOGE("[%s] Unable to configure time lapse (err %d)",
53322c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    mCodec->mComponentName.c_str(),
53332c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    err);
5334d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
53352c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
53362c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
533772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
5338d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mCreateInputBuffersSuspended) {
533972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        bool suspend = true;
534072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        err = mCodec->mOMX->setInternalOption(
534172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                mCodec->mNode,
534272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                kPortIndexInput,
534372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                IOMX::INTERNAL_OPTION_SUSPEND,
534472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                &suspend,
534572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                sizeof(suspend));
534672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
534772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
534872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("[%s] Unable to configure option to suspend (err %d)",
534994ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  mCodec->mComponentName.c_str(),
535094ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  err);
5351d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
535294ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
535394ee4b708acfa941581160b267afb79192b1d816Chong Zhang    }
535494ee4b708acfa941581160b267afb79192b1d816Chong Zhang
5355d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    return OK;
5356d291c222357303b9611cab89d0c3b047584ef377Chong Zhang}
5357d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5358d291c222357303b9611cab89d0c3b047584ef377Chong Zhangvoid ACodec::LoadedState::onCreateInputSurface(
5359d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        const sp<AMessage> & /* msg */) {
5360d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    ALOGV("onCreateInputSurface");
5361d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5362d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<AMessage> notify = mCodec->mNotify->dup();
5363d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    notify->setInt32("what", CodecBase::kWhatInputSurfaceCreated);
5364d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5365d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<IGraphicBufferProducer> bufferProducer;
5366d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    status_t err = mCodec->mOMX->createInputSurface(
5367d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            mCodec->mNode, kPortIndexInput, &bufferProducer);
5368d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5369d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (err == OK) {
5370d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        err = setupInputSurface();
5371d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    }
5372d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
53737cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err == OK) {
53747cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setObject("input-surface",
53757cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                new BufferProducerWrapper(bufferProducer));
53767cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else {
53777cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // Can't use mCodec->signalError() here -- MediaCodec won't forward
53787cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // the error through because it's in the "configured" state.  We
53797cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // send a kWhatInputSurfaceCreated with an error value instead.
53807cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGE("[%s] onCreateInputSurface returning error %d",
53817cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                mCodec->mComponentName.c_str(), err);
53827cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setInt32("err", err);
53837cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
53847cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->post();
53857cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
53867cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
5387d291c222357303b9611cab89d0c3b047584ef377Chong Zhangvoid ACodec::LoadedState::onUsePersistentInputSurface(
5388d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        const sp<AMessage> &msg) {
5389d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    ALOGV("onUsePersistentInputSurface");
5390d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5391d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<AMessage> notify = mCodec->mNotify->dup();
5392d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    notify->setInt32("what", CodecBase::kWhatInputSurfaceAccepted);
5393d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5394d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<RefBase> obj;
5395d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    CHECK(msg->findObject("input-surface", &obj));
5396d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<PersistentSurface> surface = static_cast<PersistentSurface *>(obj.get());
5397d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5398d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    status_t err = mCodec->mOMX->usePersistentInputSurface(
5399d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            mCodec->mNode, kPortIndexInput, surface->getBufferConsumer());
5400d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5401d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (err == OK) {
5402d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        err = setupInputSurface();
5403d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    }
5404d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5405d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (err != OK) {
5406d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        // Can't use mCodec->signalError() here -- MediaCodec won't forward
5407d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        // the error through because it's in the "configured" state.  We
5408d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        // send a kWhatInputSurfaceAccepted with an error value instead.
5409d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        ALOGE("[%s] onUsePersistentInputSurface returning error %d",
5410d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                mCodec->mComponentName.c_str(), err);
5411d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        notify->setInt32("err", err);
5412d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    }
5413d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    notify->post();
5414d291c222357303b9611cab89d0c3b047584ef377Chong Zhang}
5415d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5416c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onStart() {
54175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onStart");
54185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
54195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ(mCodec->mOMX->sendCommand(
54205778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
5421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
5422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->changeState(mCodec->mLoadedToIdleState);
5424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5428f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
5429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5432f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::LoadedToIdleState::stateEntered() {
54333856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
5434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5435cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    status_t err;
5436cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    if ((err = allocateBuffers()) != OK) {
543729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to allocate buffers after transitioning to IDLE state "
5438cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             "(error 0x%08x)",
5439cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             err);
5440cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
5441251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
544291bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber
544391bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber        mCodec->changeState(mCodec->mLoadedState);
5444cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    }
5445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5447f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::LoadedToIdleState::allocateBuffers() {
5448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
5449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
5451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
5452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mCodec->allocateBuffersOnPort(kPortIndexOutput);
5455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5457f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
5458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
545972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
5460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
5463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
54666507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
54676507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
54686507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
54696507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
54706507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
54716507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
54726463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatResume:
54736463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
54746463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We'll be active soon enough.
54756463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
54766463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
54776463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
54786463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatFlush:
54796463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
54806463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We haven't even started yet, so we're flushed alright...
54816463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            sp<AMessage> notify = mCodec->mNotify->dup();
5482d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
54836463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->post();
54846463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
54856463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
54866463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
5487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
5489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5492f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onOMXEvent(
5493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
5498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
5499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
5501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting),
5502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
5503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mIdleToExecutingState);
5505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5516f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
5517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5520f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToExecutingState::stateEntered() {
55213856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
5522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5524f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
5525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
552672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
5527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
5530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5533d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatResume:
5534d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
5535d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We'll be active soon enough.
5536d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
5537d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
5538d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
5539d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatFlush:
5540d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
5541d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We haven't even started yet, so we're flushed alright...
5542d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
5543d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
5544d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->post();
5545d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
5546d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
5547d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
5548d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
55496507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
55506507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
55516507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
55526507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
55536507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
55546507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
5555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
5557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5560f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onOMXEvent(
5561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
5566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateExecuting);
5567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mExecutingState->resume();
5569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingState);
5570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5581f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingState::ExecutingState(ACodec *codec)
5582349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    : BaseState(codec),
5583349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber      mActive(false) {
5584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5586f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
5587ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
5588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
5589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5591054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputMetaBuffers() {
5592054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // submit as many buffers as there are input buffers with the codec
5593054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // in case we are in port reconfiguring
5594054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
5595054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
5596054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5597054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) {
5598054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            if (mCodec->submitOutputMetaDataBuffer() != OK)
5599054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                break;
5600054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
5601054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
56024dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
56034dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
56044dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
5605054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
5606054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5607054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitRegularOutputBuffers() {
5608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
5609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
5610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mCodec->mNativeWindow != NULL) {
5612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(info->mStatus == BufferInfo::OWNED_BY_US
5613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
5614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
5616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                continue;
5617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
5619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
5620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5622ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        ALOGV("[%s] calling fillBuffer %u",
5623349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str(), info->mBufferID);
5624349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
5626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
5627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
5629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5632054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputBuffers() {
5633c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar    submitRegularOutputBuffers();
5634054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mCodec->mStoreMetaDataInOutputBuffers) {
5635054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        submitOutputMetaBuffers();
5636054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
5637054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
5638054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5639f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::resume() {
5640349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    if (mActive) {
56413856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] We're already active, no need to resume.",
5642349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str());
5643349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5644349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        return;
5645349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    }
5646349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    submitOutputBuffers();
5648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
56493cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    // Post all available input buffers
5650777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (mCodec->mBuffers[kPortIndexInput].size() == 0u) {
5651777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGW("[%s] we don't have any input buffers to resume", mCodec->mComponentName.c_str());
5652777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
5653777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim
56543cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); i++) {
56553cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
56563cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_US) {
56573cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar            postFillThisBuffer(info);
56583cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        }
56593cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    }
5660349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5661349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    mActive = true;
5662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5664f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::stateEntered() {
56653856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
5666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->processDeferredMessages();
5668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5670f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
5671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5676c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
5677c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
5678c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
5679c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5680c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mShutdownInProgress = true;
568154b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
5682c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mKeepComponentAllocated = keepComponentAllocated;
5683c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5684349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
5685349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
5687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
5688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
5689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingToIdleState);
5691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
56987a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong            ALOGV("[%s] ExecutingState flushing now "
5699ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                 "(codec owns %zu/%zu input, %zu/%zu output).",
5700d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mComponentName.c_str(),
5701d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
5702d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexInput].size(),
5703d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
5704d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexOutput].size());
5705d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
5706349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
5707349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
5709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandFlush, OMX_ALL),
5710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
5711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mFlushingState);
5713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatResume:
5718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            resume();
5720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5725496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
5726496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
5727496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            status_t err = mCodec->requestIDRFrame();
5728496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            if (err != OK) {
5729496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                ALOGW("Requesting an IDR frame failed.");
5730496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            }
5731496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5732496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            handled = true;
5733496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
5734496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
5735496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5736a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
5737a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
5738a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
5739a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
5740a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5741a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = mCodec->setParameters(params);
5742a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5743a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> reply;
5744a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            if (msg->findMessage("reply", &reply)) {
5745a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->setInt32("err", err);
5746a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->post();
5747a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            }
5748a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5749a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            handled = true;
5750a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
5751a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
5752a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
57537cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
57547cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
57556507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
57567cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
57577cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
57587cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
57597cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
57604dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
57614dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        case kWhatSubmitOutputMetaDataBufferIfEOS:
57624dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        {
57634dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            if (mCodec->mPortEOS[kPortIndexInput] &&
57644dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    !mCodec->mPortEOS[kPortIndexOutput]) {
57654dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                status_t err = mCodec->submitOutputMetaDataBuffer();
57664dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                if (err == OK) {
57674dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
57684dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                }
57694dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            }
57704dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            return true;
57714dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        }
57724dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
5773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5775f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5781a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t ACodec::setParameters(const sp<AMessage> &params) {
5782a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    int32_t videoBitrate;
5783530fdbdc1b5491f3fbf172752834d1515701e142Lajos Molnar    if (params->findInt32("video-bitrate", &videoBitrate)) {
5784a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        OMX_VIDEO_CONFIG_BITRATETYPE configParams;
5785a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        InitOMXParams(&configParams);
5786a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nPortIndex = kPortIndexOutput;
5787a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nEncodeBitrate = videoBitrate;
5788a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5789a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        status_t err = mOMX->setConfig(
5790a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                mNode,
5791a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                OMX_IndexConfigVideoBitrate,
5792a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                &configParams,
5793a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                sizeof(configParams));
5794a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5795a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        if (err != OK) {
5796a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
5797a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                   videoBitrate, err);
5798a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5799a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            return err;
5800a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
5801a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    }
5802a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
580372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    int64_t skipFramesBeforeUs;
580472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (params->findInt64("skip-frames-before", &skipFramesBeforeUs)) {
580572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        status_t err =
580672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mOMX->setInternalOption(
580772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     mNode,
580872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     kPortIndexInput,
580972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     IOMX::INTERNAL_OPTION_START_TIME,
581072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     &skipFramesBeforeUs,
581172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     sizeof(skipFramesBeforeUs));
581272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
581372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
581472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("Failed to set parameter 'skip-frames-before' (err %d)", err);
581572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            return err;
581672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
581772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
581872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
5819e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    int32_t dropInputFrames;
5820e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    if (params->findInt32("drop-input-frames", &dropInputFrames)) {
5821e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        bool suspend = dropInputFrames != 0;
5822e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
5823b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err =
5824b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            mOMX->setInternalOption(
5825e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     mNode,
5826e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     kPortIndexInput,
5827e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     IOMX::INTERNAL_OPTION_SUSPEND,
5828e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     &suspend,
5829b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber                     sizeof(suspend));
5830b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
5831b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
5832b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err);
5833b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
5834b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
5835b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    }
5836b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
5837b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    int32_t dummy;
5838b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    if (params->findInt32("request-sync", &dummy)) {
5839b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err = requestIDRFrame();
5840b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
5841b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
5842b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Requesting a sync frame failed w/ err %d", err);
5843b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
5844b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
5845e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    }
5846e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
58478db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    float rate;
58488db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    if (params->findFloat("operating-rate", &rate) && rate > 0) {
58498db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        status_t err = setOperatingRate(rate, mIsVideo);
58508db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        if (err != OK) {
58518db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu            ALOGE("Failed to set parameter 'operating-rate' (err %d)", err);
58528db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu            return err;
58538db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        }
58548db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    }
58558db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu
5856a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return OK;
5857a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
5858a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
58596507d14c6d10f93d390de62b9eed267f9b544985Andy McFaddenvoid ACodec::onSignalEndOfInputStream() {
58606507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    sp<AMessage> notify = mNotify->dup();
5861d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatSignaledInputEOS);
58626507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
58636507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    status_t err = mOMX->signalEndOfInputStream(mNode);
58646507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    if (err != OK) {
58656507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        notify->setInt32("err", err);
58666507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    }
58676507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->post();
58686507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden}
58696507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
5870f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onOMXEvent(
5871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventPortSettingsChanged:
5874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
5876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
587731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
5878054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mCodec->mMetaDataBuffersToSubmit = 0;
5879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
5880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
5881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_CommandPortDisable, kPortIndexOutput),
5882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
5883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5884349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                mCodec->freeOutputBuffersNotOwnedByComponent();
5885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
588731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            } else if (data2 == OMX_IndexConfigCommonOutputCrop) {
588831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
5889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
5890ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08x",
5891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->mComponentName.c_str(), data2);
5892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventBufferFlag:
5898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5909f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
5910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ACodec *codec)
5911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5914f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
5915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
5916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput) {
5917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return FREE_BUFFERS;
5918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
5921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
5923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5925f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onMessageReceived(
5926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
5927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5932349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case kWhatResume:
5933e6eea3a6b6e0cf92287ec1ceb8350f201d17e1acPer Persson        case kWhatSetParameters:
5934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5935349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            if (msg->what() == kWhatResume) {
59363856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
5937349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            }
5938349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
5940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5952f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::OutputPortSettingsChangedState::stateEntered() {
59533856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now handling output port settings change",
5954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mCodec->mComponentName.c_str());
5955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5957f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onOMXEvent(
5958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
5963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
5964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
59653856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now disabled.",
5966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
5967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mCodec->mBuffers[kPortIndexOutput].isEmpty());
5969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mDealer[kPortIndexOutput].clear();
5970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
5972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput),
5973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
5974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5975cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                status_t err;
5976cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                if ((err = mCodec->allocateBuffersOnPort(
5977cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                                kPortIndexOutput)) != OK) {
597829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("Failed to allocate output port buffers after "
5979cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         "port reconfiguration (error 0x%08x)",
5980cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         err);
5981cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
5982251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5983d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
5984755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // This is technically not correct, but appears to be
5985755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the only way to free the component instance.
5986755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // Controlled transitioning from excecuting->idle
5987755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // and idle->loaded seem impossible probably because
5988755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the output port never finishes re-enabling.
5989755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mShutdownInProgress = true;
5990755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mKeepComponentAllocated = false;
5991755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->changeState(mCodec->mLoadedState);
5992cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                }
5993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
5995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
5996777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (data2 != (OMX_U32)kPortIndexOutput) {
5997777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGW("ignoring EventCmdComplete OMX_CommandPortEnable for port %u", data2);
5998777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return false;
5999777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
6000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
600131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
600231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
60033856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now reenabled.",
6004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
6005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6006349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                if (mCodec->mExecutingState->active()) {
6007349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    mCodec->mExecutingState->submitOutputBuffers();
6008349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                }
6009349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mExecutingState);
6011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
6013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
6014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
6016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
6020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
6024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6025f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
60265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : BaseState(codec),
60275778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mComponentNowIdle(false) {
6028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6030f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
6031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
6032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
6034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
6035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
6037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
6038777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("Got flush request in IdleToLoadedState");
6039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
6043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
6045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
6052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
6056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6058f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::stateEntered() {
60593856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
606031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
60615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mComponentNowIdle = false;
606231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mCodec->mSentFormat = false;
6063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6065f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onOMXEvent(
6066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
6068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
6069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
6071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
6072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
60735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mComponentNowIdle = true;
60745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            changeStateIfWeOwnAllBuffers();
6076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6080349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
6081349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventBufferFlag:
6082349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
6083349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We're shutting down and don't care about this anymore.
6084349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
6085349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
6086349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
6089f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
60910af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
6092f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
60935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
6094f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->sendCommand(
6095f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded),
6096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
6097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexInput), (status_t)OK);
6099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexOutput), (status_t)OK);
6100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
61010167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown)
61020167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && mCodec->mNativeWindow != NULL) {
6103bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // We push enough 1x1 blank buffers to ensure that one of
6104bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // them has made it to the display.  This allows the OMX
6105bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // component teardown to zero out any protected buffers
6106bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // without the risk of scanning out one of those buffers.
6107b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar            pushBlankBuffersToNativeWindow(mCodec->mNativeWindow.get());
6108bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
6109bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
6110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mIdleToLoadedState);
6111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6114f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onInputBufferFilled(
6115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
6116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
6117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
6119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6121f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onOutputBufferDrained(
6122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
6123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
6124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
6126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
6129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6130f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
6131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
6132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6134f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
6135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
6136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
6138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
6139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
6141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
6147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
6149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
6150777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGW("Ignoring flush request in ExecutingToIdleState");
6151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
6156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
6160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6162f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToLoadedState::stateEntered() {
61633856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
6164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6166f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onOMXEvent(
6167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
6169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
6170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
6172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateLoaded);
6173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6174c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->changeState(mCodec->mLoadedState);
6175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
6181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
6185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6186f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::FlushingState::FlushingState(ACodec *codec)
6187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
6188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6190f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::stateEntered() {
61913856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
6192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
6194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6196f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
6197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
6198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
6200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
6201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
6203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
6207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing this right now.
6209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
6215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
6219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6221f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onOMXEvent(
6222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6223ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGV("[%s] FlushingState onOMXEvent(%u,%d)",
6224ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar            mCodec->mComponentName.c_str(), event, (OMX_S32)data1);
6225d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
6226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
6227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
6228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandFlush);
6230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
6232777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (mFlushComplete[data2]) {
6233777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGW("Flush already completed for %s port",
6234777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            data2 == kPortIndexInput ? "input" : "output");
6235777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return true;
6236777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
6237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mFlushComplete[data2] = true;
6238e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber
6239e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                if (mFlushComplete[kPortIndexInput]
6240e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                        && mFlushComplete[kPortIndexOutput]) {
6241e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                    changeStateIfWeOwnAllBuffers();
6242e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                }
6243777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            } else if (data2 == OMX_ALL) {
6244777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (!mFlushComplete[kPortIndexInput] || !mFlushComplete[kPortIndexOutput]) {
6245777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGW("received flush complete event for OMX_ALL before ports have been"
6246777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            "flushed (%d/%d)",
6247777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mFlushComplete[kPortIndexInput], mFlushComplete[kPortIndexOutput]);
6248777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return false;
6249777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
6250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                changeStateIfWeOwnAllBuffers();
6252777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            } else {
6253777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                ALOGW("data2 not OMX_ALL but %u in EventCmdComplete CommandFlush", data2);
6254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
6255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6259349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
6260349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
62611d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec);
6262349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("type", omx_message::EVENT);
6263609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            msg->setInt32("node", mCodec->mNode);
6264349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("event", event);
6265349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data1", data1);
6266349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data2", data2);
6267349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
62683856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
6269349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                 mCodec->mComponentName.c_str());
6270349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6271349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mCodec->deferMessage(msg);
6272349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6273349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
6274349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
6275349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
6278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
6281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6283f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
6284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
6285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
6287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6289f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
6290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
6291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
6293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6295f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
6296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mFlushComplete[kPortIndexInput]
6297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mFlushComplete[kPortIndexOutput]
6298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mCodec->allYourBuffersAreBelongToUs()) {
62997e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // We now own all buffers except possibly those still queued with
63007e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // the native window for rendering. Let's get those back as well.
63017e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
63027e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
6303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
6304d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatFlushCompleted);
6305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->post();
6306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->mPortEOS[kPortIndexInput] =
6308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mPortEOS[kPortIndexOutput] = false;
6309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6310dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber        mCodec->mInputEOSResult = OK;
6311dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
6312f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        if (mCodec->mSkipCutBuffer != NULL) {
6313f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen            mCodec->mSkipCutBuffer->clear();
6314f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        }
6315f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen
6316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mExecutingState);
6317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
6321