ACodec.cpp revision 3fb3917ae19f07ddfb2176a9da3c7cfa514522a5
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
27f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/ACodec.h>
28f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
29f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <binder/MemoryDealer.h>
30f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/hexdump.h>
32f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ABuffer.h>
33f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ADebug.h>
34f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/AMessage.h>
35a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar#include <media/stagefright/foundation/AUtils.h>
36f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
377cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden#include <media/stagefright/BufferProducerWrapper.h>
38afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber#include <media/stagefright/MediaCodecList.h>
39f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaDefs.h>
401173118eace0e9e347cb007f0da817cee87579edGlenn Kasten#include <media/stagefright/NativeWindowWrapper.h>
41f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/OMXClient.h>
421065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber#include <media/stagefright/OMXCodec.h>
43f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
443a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber#include <media/hardware/HardwareAPI.h>
453a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
4697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu#include <OMX_AudioExt.h>
474154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev#include <OMX_VideoExt.h>
48f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <OMX_Component.h>
4997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu#include <OMX_IndexExt.h>
50f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
51496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#include "include/avc_utils.h"
52496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
53f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android {
54f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
55251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// OMX errors are directly mapped into status_t range if
56251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// there is no corresponding MediaError status code.
57251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Use the statusFromOMXError(int32_t omxError) function.
58251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung//
59251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Currently this is a direct map.
60251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// See frameworks/native/include/media/openmax/OMX_Core.h
61251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung//
62251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Vendor OMX errors     from 0x90000000 - 0x9000FFFF
63251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Extension OMX errors  from 0x8F000000 - 0x90000000
64251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Standard OMX errors   from 0x80001000 - 0x80001024 (0x80001024 current)
65251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung//
66251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
67251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// returns true if err is a recognized OMX error code.
68251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// as OMX error is OMX_S32, this is an int32_t type
69251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hungstatic inline bool isOMXError(int32_t err) {
70251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    return (ERROR_CODEC_MIN <= err && err <= ERROR_CODEC_MAX);
71251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung}
72251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
73251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// converts an OMX error to a status_t
74251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hungstatic inline status_t statusFromOMXError(int32_t omxError) {
75251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    switch (omxError) {
76251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case OMX_ErrorInvalidComponentName:
77251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case OMX_ErrorComponentNotFound:
78251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return NAME_NOT_FOUND; // can trigger illegal argument error for provided names.
79251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    default:
80251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return isOMXError(omxError) ? omxError : 0; // no translation required
81251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
82251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung}
83251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
84251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// checks and converts status_t to a non-side-effect status_t
85251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hungstatic inline status_t makeNoSideEffectStatus(status_t err) {
86251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    switch (err) {
87251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // the following errors have side effects and may come
88251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // from other code modules. Remap for safety reasons.
89251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case INVALID_OPERATION:
90251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case DEAD_OBJECT:
91251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return UNKNOWN_ERROR;
92251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    default:
93251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return err;
94251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
95251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung}
96251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
97f933441648ef6a71dee783d733aac17b9508b452Andreas Hubertemplate<class T>
98f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic void InitOMXParams(T *params) {
99f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nSize = sizeof(T);
100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nVersionMajor = 1;
101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nVersionMinor = 0;
102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nRevision = 0;
103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nStep = 0;
104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
106f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct CodecObserver : public BnOMXObserver {
107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CodecObserver() {}
108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void setNotificationMessage(const sp<AMessage> &msg) {
110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mNotify = msg;
111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // from IOMXObserver
114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onMessage(const omx_message &omx_msg) {
115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> msg = mNotify->dup();
116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->setInt32("type", omx_msg.type);
118609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        msg->setInt32("node", omx_msg.node);
119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        switch (omx_msg.type) {
121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::EVENT:
122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("event", omx_msg.u.event_data.event);
124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("data1", omx_msg.u.event_data.data1);
125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("data2", omx_msg.u.event_data.data2);
126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::EMPTY_BUFFER_DONE:
130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
131609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                msg->setInt32("buffer", omx_msg.u.buffer_data.buffer);
132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::FILL_BUFFER_DONE:
136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
137609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                msg->setInt32(
138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "buffer", omx_msg.u.extended_buffer_data.buffer);
139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "range_offset",
141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.range_offset);
142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "range_length",
144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.range_length);
145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "flags",
147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.flags);
148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt64(
149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "timestamp",
150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.timestamp);
151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            default:
155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                TRESPASS();
156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->post();
160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
162f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual ~CodecObserver() {}
164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
165f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> mNotify;
167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(CodecObserver);
169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
173f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::BaseState : public AState {
174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState(ACodec *codec, const sp<AState> &parentState = NULL);
175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
176f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    enum PortMode {
178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        KEEP_BUFFERS,
179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        RESUBMIT_BUFFERS,
180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        FREE_BUFFERS,
181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ACodec *mCodec;
184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void postFillThisBuffer(BufferInfo *info);
195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
196f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXMessage(const sp<AMessage> &msg);
198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXEmptyBufferDone(IOMX::buffer_id bufferID);
200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXFillBufferDone(
202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID,
203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            size_t rangeOffset, size_t rangeLength,
204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            OMX_U32 flags,
205784e24e386b088c05d653ab482f2e95cb53e3d01Andy Hung            int64_t timeUs);
206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void getMoreInputDataIfPossible();
208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(BaseState);
210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
214ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberstruct ACodec::DeathNotifier : public IBinder::DeathRecipient {
215ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    DeathNotifier(const sp<AMessage> &notify)
216ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        : mNotify(notify) {
217ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
218ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
219ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual void binderDied(const wp<IBinder> &) {
220ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mNotify->post();
221ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
222ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
223ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprotected:
224ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual ~DeathNotifier() {}
225ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
226ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprivate:
227ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> mNotify;
228ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
229ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(DeathNotifier);
230ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber};
231ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
232f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::UninitializedState : public ACodec::BaseState {
233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    UninitializedState(ACodec *codec);
234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
235f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
237c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
239f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void onSetup(const sp<AMessage> &msg);
241c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onAllocateComponent(const sp<AMessage> &msg);
242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
243ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<DeathNotifier> mDeathNotifier;
244ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(UninitializedState);
246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
250c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberstruct ACodec::LoadedState : public ACodec::BaseState {
251c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    LoadedState(ACodec *codec);
252c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
253c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprotected:
254c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
255c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
256c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
257c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprivate:
258c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    friend struct ACodec::UninitializedState;
259c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
260c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onConfigureComponent(const sp<AMessage> &msg);
2617cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    void onCreateInputSurface(const sp<AMessage> &msg);
262c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onStart();
263c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onShutdown(bool keepComponentAllocated);
264c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
265c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedState);
266c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber};
267c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
268c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
269c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
270f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::LoadedToIdleState : public ACodec::BaseState {
271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    LoadedToIdleState(ACodec *codec);
272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
273f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
278f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t allocateBuffers();
280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedToIdleState);
282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
286f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToExecutingState : public ACodec::BaseState {
287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToExecutingState(ACodec *codec);
288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
289f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
294f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToExecutingState);
296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
300f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingState : public ACodec::BaseState {
301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingState(ACodec *codec);
302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
303054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitRegularOutputBuffers();
304054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitOutputMetaBuffers();
305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void submitOutputBuffers();
306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Submit output buffers to the decoder, submit input buffers to client
308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // to fill with data.
309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void resume();
310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
311349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    // Returns true iff input and output buffers are in play.
312349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool active() const { return mActive; }
313349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
314f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
321f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
322349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool mActive;
323349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingState);
325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
329f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::OutputPortSettingsChangedState : public ACodec::BaseState {
330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OutputPortSettingsChangedState(ACodec *codec);
331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
332f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
339f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(OutputPortSettingsChangedState);
341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
345f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingToIdleState : public ACodec::BaseState {
346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingToIdleState(ACodec *codec);
347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
348f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
357f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool mComponentNowIdle;
3615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingToIdleState);
363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
367f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToLoadedState : public ACodec::BaseState {
368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToLoadedState(ACodec *codec);
369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
370f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
376f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToLoadedState);
378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
382f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::FlushingState : public ACodec::BaseState {
383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    FlushingState(ACodec *codec);
384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
385f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
394f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool mFlushComplete[2];
396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(FlushingState);
400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
404f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ACodec()
405afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    : mQuirks(0),
406609b815a3131d22da38b2f452faa9f89daad4039Andy Hung      mNode(0),
4075778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mSentFormat(false),
408c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber      mIsEncoder(false),
409308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang      mUseMetadataOnEncoderOutput(false),
4109806555d3930be43e11106281dee354820ac1c88Andreas Huber      mShutdownInProgress(false),
41154b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar      mExplicitShutdown(false),
4129806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderDelay(0),
4139806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderPadding(0),
414e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang      mRotationDegrees(0),
4159806555d3930be43e11106281dee354820ac1c88Andreas Huber      mChannelMaskPresent(false),
416054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mChannelMask(0),
417054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mDequeueCounter(0),
418054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mStoreMetaDataInOutputBuffers(false),
419a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber      mMetaDataBuffersToSubmit(0),
42094ee4b708acfa941581160b267afb79192b1d816Chong Zhang      mRepeatFrameDelayUs(-1ll),
4212c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang      mMaxPtsGapUs(-1ll),
4222c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang      mTimePerFrameUs(-1ll),
423609b815a3131d22da38b2f452faa9f89daad4039Andy Hung      mTimePerCaptureUs(-1ll),
424ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad      mCreateInputBuffersSuspended(false),
425ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad      mTunneled(false) {
426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mUninitializedState = new UninitializedState(this);
427c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mLoadedState = new LoadedState(this);
428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mLoadedToIdleState = new LoadedToIdleState(this);
429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToExecutingState = new IdleToExecutingState(this);
430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingState = new ExecutingState(this);
431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOutputPortSettingsChangedState =
433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        new OutputPortSettingsChangedState(this);
434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingToIdleState = new ExecutingToIdleState(this);
436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToLoadedState = new IdleToLoadedState(this);
437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushingState = new FlushingState(this);
438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
440dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber    mInputEOSResult = OK;
441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeState(mUninitializedState);
443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
445f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::~ACodec() {
446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
448f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::setNotificationMessage(const sp<AMessage> &msg) {
449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mNotify = msg;
450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
452f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::initiateSetup(const sp<AMessage> &msg) {
453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setWhat(kWhatSetup);
454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setTarget(id());
455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
458a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Hubervoid ACodec::signalSetParameters(const sp<AMessage> &params) {
459a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    sp<AMessage> msg = new AMessage(kWhatSetParameters, id());
460a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->setMessage("params", params);
461a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->post();
462a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
463a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4645778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateAllocateComponent(const sp<AMessage> &msg) {
4655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatAllocateComponent);
4665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
4675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4685778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4705778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateConfigureComponent(const sp<AMessage> &msg) {
4715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatConfigureComponent);
4725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
4735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4745778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4767cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::initiateCreateInputSurface() {
4777cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    (new AMessage(kWhatCreateInputSurface, id()))->post();
4787cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
4797cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4807cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::signalEndOfInputStream() {
4817cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    (new AMessage(kWhatSignalEndOfInputStream, id()))->post();
4827cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
4837cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4845778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateStart() {
4855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    (new AMessage(kWhatStart, id()))->post();
4865778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
488f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalFlush() {
4897a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] signalFlush", mComponentName.c_str());
490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatFlush, id()))->post();
491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
493f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalResume() {
494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatResume, id()))->post();
495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
497c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::initiateShutdown(bool keepComponentAllocated) {
498c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> msg = new AMessage(kWhatShutdown, id());
499c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->setInt32("keepComponentAllocated", keepComponentAllocated);
500c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->post();
50130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar    if (!keepComponentAllocated) {
50230358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        // ensure shutdown completes in 3 seconds
50330358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        (new AMessage(kWhatReleaseCodecInstance, id()))->post(3000000);
50430358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar    }
505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
507496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubervoid ACodec::signalRequestIDRFrame() {
508496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    (new AMessage(kWhatRequestIDRFrame, id()))->post();
509496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
510496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5114dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
5124dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// Some codecs may return input buffers before having them processed.
5134dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// This causes a halt if we already signaled an EOS on the input
5144dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// port.  For now keep submitting an output buffer if there was an
5154dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// EOS on the input port, but not yet on the output port.
5164dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnarvoid ACodec::signalSubmitOutputMetaDataBufferIfEOS_workaround() {
5174dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    if (mPortEOS[kPortIndexInput] && !mPortEOS[kPortIndexOutput] &&
5184dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            mMetaDataBuffersToSubmit > 0) {
5194dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        (new AMessage(kWhatSubmitOutputMetaDataBufferIfEOS, id()))->post();
5204dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    }
5214dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar}
5224dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
523f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mDealer[portIndex] == NULL);
527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mBuffers[portIndex].isEmpty());
528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
531054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (mStoreMetaDataInOutputBuffers) {
532054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputMetaDataBuffers();
533054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
534054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputBuffersFromNativeWindow();
535054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
5365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
5375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
5385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
5395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = portIndex;
540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
5425778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err == OK) {
545609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGV("[%s] Allocating %u buffers of size %u on %s port",
5465778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mComponentName.c_str(),
5475778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    def.nBufferCountActual, def.nBufferSize,
5485778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    portIndex == kPortIndexInput ? "input" : "output");
549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            size_t totalSize = def.nBufferCountActual * def.nBufferSize;
5515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
5545778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
5555778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(mem.get() != NULL);
556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
557ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                BufferInfo info;
558ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                info.mStatus = BufferInfo::OWNED_BY_US;
559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
560afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                uint32_t requiresAllocateBufferBit =
561afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                    (portIndex == kPortIndexInput)
562afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        ? OMXCodec::kRequiresAllocateBufferOnInputPorts
563afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        : OMXCodec::kRequiresAllocateBufferOnOutputPorts;
5641065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
565308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                if ((portIndex == kPortIndexInput && (mFlags & kFlagIsSecure))
566308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        || mUseMetadataOnEncoderOutput) {
567ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    mem.clear();
568ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
569ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    void *ptr;
570ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->allocateBuffer(
571ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, def.nBufferSize, &info.mBufferID,
572ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            &ptr);
573ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
574308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    int32_t bufSize = mUseMetadataOnEncoderOutput ?
575308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                            (4 + sizeof(buffer_handle_t)) : def.nBufferSize;
576308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
577308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    info.mData = new ABuffer(ptr, bufSize);
578ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                } else if (mQuirks & requiresAllocateBufferBit) {
5795778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    err = mOMX->allocateBufferWithBackup(
580ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, mem, &info.mBufferID);
5815778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
582ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->useBuffer(mNode, portIndex, mem, &info.mBufferID);
583ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                }
584ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
585ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                if (mem != NULL) {
586ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    info.mData = new ABuffer(mem->pointer(), def.nBufferSize);
5875778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
5881065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
5895778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mBuffers[portIndex].push(info);
5901065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            }
5911065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
5925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
5955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
5965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> notify = mNotify->dup();
599d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatBuffersAllocated);
6005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("portIndex", portIndex);
602eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
603eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    sp<PortDescription> desc = new PortDescription;
604eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
6055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
606eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        const BufferInfo &info = mBuffers[portIndex][i];
6075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
608eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        desc->addBuffer(info.mBufferID, info.mData);
609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
611eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    notify->setObject("portDesc", desc);
6125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->post();
6135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
617054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::configureOutputBuffersFromNativeWindow(
618054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 *bufferCount, OMX_U32 *bufferSize,
619054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 *minUndequeuedBuffers) {
620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = kPortIndexOutput;
623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffers_geometry(
632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameWidth,
634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameHeight,
635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.eColorFormat);
636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
63829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffers_geometry failed: %s (%d)",
639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                strerror(-err), -err);
640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
643e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang    if (mRotationDegrees != 0) {
644e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        uint32_t transform = 0;
645e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        switch (mRotationDegrees) {
646e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            case 0: transform = 0; break;
647e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            case 90: transform = HAL_TRANSFORM_ROT_90; break;
648e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            case 180: transform = HAL_TRANSFORM_ROT_180; break;
649e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            case 270: transform = HAL_TRANSFORM_ROT_270; break;
650e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            default: transform = 0; break;
651e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        }
652e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang
653e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        if (transform > 0) {
654e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            err = native_window_set_buffers_transform(
655e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang                    mNativeWindow.get(), transform);
656e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            if (err != 0) {
657e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang                ALOGE("native_window_set_buffers_transform failed: %s (%d)",
658e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang                        strerror(-err), -err);
659e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang                return err;
660e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            }
661e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        }
662e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang    }
663e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang
664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Set up the native window.
6653c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    OMX_U32 usage = 0;
6663c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
6673c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    if (err != 0) {
6685ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("querying usage flags from OMX IL component failed: %d", err);
6693c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        // XXX: Currently this error is logged, but not fatal.
6703c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        usage = 0;
6713c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    }
6723c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis
6731713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang    if (mFlags & kFlagIsGrallocUsageProtected) {
674bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        usage |= GRALLOC_USAGE_PROTECTED;
675bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
676bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
677bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // Make sure to check whether either Stagefright or the video decoder
678bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // requested protected buffers.
679bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (usage & GRALLOC_USAGE_PROTECTED) {
680bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Verify that the ANativeWindow sends images directly to
681bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // SurfaceFlinger.
682bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        int queuesToNativeWindow = 0;
683bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->query(
684bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                mNativeWindow.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
685bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                &queuesToNativeWindow);
686bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != 0) {
687bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error authenticating native window: %d", err);
688bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
689bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
690bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (queuesToNativeWindow != 1) {
691bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("native window could not be authenticated");
692bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return PERMISSION_DENIED;
693bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
694bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
695bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_usage(
697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
6983c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis            usage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP);
699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
70129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err);
702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
705ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // Exits here for tunneled video playback codecs -- i.e. skips native window
706ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // buffer allocation step as this is managed by the tunneled OMX omponent
707ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // itself and explicitly sets def.nBufferCountActual to 0.
708ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    if (mTunneled) {
709ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        ALOGV("Tunneled Playback: skipping native window buffer allocation.");
710ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        def.nBufferCountActual = 0;
711ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        err = mOMX->setParameter(
712ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
713ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
714ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *minUndequeuedBuffers = 0;
715ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *bufferCount = 0;
716ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *bufferSize = 0;
717ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        return err;
718ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    }
719ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
720054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *minUndequeuedBuffers = 0;
721258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    err = mNativeWindow->query(
722258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
723054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (int *)minUndequeuedBuffers);
724258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
725258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    if (err != 0) {
72629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
727258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                strerror(-err), -err);
728258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        return err;
729258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
730258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
731e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // FIXME: assume that surface is controlled by app (native window
732e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // returns the number for the case when surface is not controlled by app)
7331faa41704e0b976e546321effcb09a85767d51baLajos Molnar    // FIXME2: This means that minUndeqeueudBufs can be 1 larger than reported
7341faa41704e0b976e546321effcb09a85767d51baLajos Molnar    // For now, try to allocate 1 more buffer, but don't fail if unsuccessful
735e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar
736e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // Use conservative allocation while also trying to reduce starvation
737e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //
738e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // 1. allocate at least nBufferCountMin + minUndequeuedBuffers - that is the
739e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //    minimum needed for the consumer to be able to work
740e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // 2. try to allocate two (2) additional buffers to reduce starvation from
741e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //    the consumer
7421faa41704e0b976e546321effcb09a85767d51baLajos Molnar    //    plus an extra buffer to account for incorrect minUndequeuedBufs
7431faa41704e0b976e546321effcb09a85767d51baLajos Molnar    for (OMX_U32 extraBuffers = 2 + 1; /* condition inside loop */; extraBuffers--) {
744e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        OMX_U32 newBufferCount =
745e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            def.nBufferCountMin + *minUndequeuedBuffers + extraBuffers;
746258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        def.nBufferCountActual = newBufferCount;
747258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        err = mOMX->setParameter(
748258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
749258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
750e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        if (err == OK) {
751e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            *minUndequeuedBuffers += extraBuffers;
752e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            break;
753e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        }
754e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar
755609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGW("[%s] setting nBufferCountActual to %u failed: %d",
756e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar                mComponentName.c_str(), newBufferCount, err);
757e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        /* exit condition */
758e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        if (extraBuffers == 0) {
759258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            return err;
760258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        }
761258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
762258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffer_count(
764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(), def.nBufferCountActual);
765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
76729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                -err);
769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
772054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferCount = def.nBufferCountActual;
773054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferSize =  def.nBufferSize;
774054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
775054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
776054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
777054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputBuffersFromNativeWindow() {
778054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
779054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
780054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
781054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
782054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
783e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    mNumUndequeuedBuffers = minUndequeuedBuffers;
784054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
785609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Allocating %u buffers from a native window of size %u on "
786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         "output port",
787054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount, bufferSize);
788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Dequeue buffers and send them to OMX
790054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
7918ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev        ANativeWindowBuffer *buf;
7921e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
79429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
79974006804065941841883c4b46ee785070164023fJamie Gennis        BufferInfo info;
80074006804065941841883c4b46ee785070164023fJamie Gennis        info.mStatus = BufferInfo::OWNED_BY_US;
801054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(NULL /* data */, bufferSize /* capacity */);
80274006804065941841883c4b46ee785070164023fJamie Gennis        info.mGraphicBuffer = graphicBuffer;
80374006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].push(info);
80474006804065941841883c4b46ee785070164023fJamie Gennis
805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferId;
806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &bufferId);
808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
809609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGE("registering GraphicBuffer %u with OMX IL component failed: "
81074006804065941841883c4b46ee785070164023fJamie Gennis                 "%d", i, err);
811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
81474006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
81574006804065941841883c4b46ee785070164023fJamie Gennis
816609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGV("[%s] Registered graphic buffer with ID %u (pointer = %p)",
817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mComponentName.c_str(),
818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             bufferId, graphicBuffer.get());
819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelStart;
822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelEnd;
823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // If an error occurred while dequeuing we need to cancel any buffers
826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // that were dequeued.
827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelStart = 0;
82874006804065941841883c4b46ee785070164023fJamie Gennis        cancelEnd = mBuffers[kPortIndexOutput].size();
829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
830054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // Return the required minimum undequeued buffers to the native window.
831054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelStart = bufferCount - minUndequeuedBuffers;
832054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelEnd = bufferCount;
833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
8373fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        status_t error = cancelBufferToNativeWindow(info);
8383fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        if (err == 0) {
8393fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia            err = error;
8403fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        }
841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
846054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputMetaDataBuffers() {
847054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
848054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
849054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
850054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
851054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
852e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    mNumUndequeuedBuffers = minUndequeuedBuffers;
853054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
854609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Allocating %u meta buffers on output port",
855054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount);
856054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
857054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    size_t totalSize = bufferCount * 8;
858054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mDealer[kPortIndexOutput] = new MemoryDealer(totalSize, "ACodec");
859054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
860054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // Dequeue buffers and send them to OMX
861054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
862054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo info;
863054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
864054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mGraphicBuffer = NULL;
865054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mDequeuedAt = mDequeueCounter;
866054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
867054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        sp<IMemory> mem = mDealer[kPortIndexOutput]->allocate(
868054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                sizeof(struct VideoDecoderOutputMetaData));
869054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(mem.get() != NULL);
870054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(mem->pointer(), mem->size());
871054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
872054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // we use useBuffer for metadata regardless of quirks
873054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        err = mOMX->useBuffer(
874054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mNode, kPortIndexOutput, mem, &info.mBufferID);
875054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
876054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        mBuffers[kPortIndexOutput].push(info);
877054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
878609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGV("[%s] allocated meta buffer with ID %u (pointer = %p)",
879054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mComponentName.c_str(), info.mBufferID, mem->pointer());
880054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
881054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
882054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mMetaDataBuffersToSubmit = bufferCount - minUndequeuedBuffers;
883054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
884054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
885054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
886054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::submitOutputMetaDataBuffer() {
887054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mStoreMetaDataInOutputBuffers);
888054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mMetaDataBuffersToSubmit == 0)
889054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return OK;
890054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
891054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *info = dequeueBufferFromNativeWindow();
892054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (info == NULL)
893054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return ERROR_IO;
894054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
895609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] submitting output meta buffer ID %u for graphic buffer %p",
896054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          mComponentName.c_str(), info->mBufferID, info->mGraphicBuffer.get());
897054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
898054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    --mMetaDataBuffersToSubmit;
899054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK_EQ(mOMX->fillBuffer(mNode, info->mBufferID),
900054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             (status_t)OK);
901054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
902054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
903054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return OK;
904054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
905054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
906f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
909609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Calling cancelBuffer on buffer %u",
910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mComponentName.c_str(), info->mBufferID);
911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int err = mNativeWindow->cancelBuffer(
9131e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        mNativeWindow.get(), info->mGraphicBuffer.get(), -1);
914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9153fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia    ALOGW_IF(err != 0, "[%s] can not return buffer %u to native window",
9163fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia            mComponentName.c_str(), info->mBufferID);
917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9203fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia    return err;
921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
923f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
9248ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev    ANativeWindowBuffer *buf;
9251e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    int fenceFd = -1;
926054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mNativeWindow.get() != NULL);
927ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
928ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    if (mTunneled) {
929ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        ALOGW("dequeueBufferFromNativeWindow() should not be called in tunnel"
930ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad              " video playback mode mode!");
931ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        return NULL;
932ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    }
933ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
9341e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    if (native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf) != 0) {
93529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("dequeueBuffer failed.");
936c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber        return NULL;
937c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
939054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *oldest = NULL;
940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
944054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mGraphicBuffer != NULL &&
945054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            info->mGraphicBuffer->handle == buf->handle) {
946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus,
947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (int)BufferInfo::OWNED_BY_NATIVE_WINDOW);
948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
953054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
954054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW &&
955054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (oldest == NULL ||
956054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             // avoid potential issues from counter rolling over
957054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mDequeueCounter - info->mDequeuedAt >
958054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    mDequeueCounter - oldest->mDequeuedAt)) {
959054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            oldest = info;
960054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
961054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
962054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
963054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (oldest) {
964054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(mStoreMetaDataInOutputBuffers);
965054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
966054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // discard buffer in LRU info and replace with new buffer
967054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mGraphicBuffer = new GraphicBuffer(buf, false);
968054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mStatus = BufferInfo::OWNED_BY_US;
969054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
970d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        mOMX->updateGraphicBufferInMeta(
971d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                mNode, kPortIndexOutput, oldest->mGraphicBuffer,
972d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                oldest->mBufferID);
973054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
974d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        VideoDecoderOutputMetaData *metaData =
975d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar            reinterpret_cast<VideoDecoderOutputMetaData *>(
976d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                    oldest->mData->base());
977d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        CHECK_EQ(metaData->eType, kMetadataBufferTypeGrallocSource);
978d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar
979d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
980054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                oldest - &mBuffers[kPortIndexOutput][0],
981054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mDequeueCounter - oldest->mDequeuedAt,
982d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                metaData->pHandle,
983d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                oldest->mGraphicBuffer->handle, oldest->mData->base());
984054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
985054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return oldest;
986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
993f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[portIndex].size(); i-- > 0;) {
995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, freeBuffer(portIndex, i));
996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDealer[portIndex].clear();
999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1003349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huberstatus_t ACodec::freeOutputBuffersNotOwnedByComponent() {
1004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
1005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
1006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
1007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10082ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // At this time some buffers may still be with the component
10092ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // or being drained.
10102ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT &&
10112ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar            info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) {
1012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK, freeBuffer(kPortIndexOutput, i));
1013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1019f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
1020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
1021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(info->mStatus == BufferInfo::OWNED_BY_US
1023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
1024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput && mNativeWindow != NULL
1026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && info->mStatus == BufferInfo::OWNED_BY_US) {
10273fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        cancelBufferToNativeWindow(info);
1028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(mOMX->freeBuffer(
1031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, portIndex, info->mBufferID),
1032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
1033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mBuffers[portIndex].removeAt(i);
1035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1039f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::findBufferByID(
1040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        uint32_t portIndex, IOMX::buffer_id bufferID,
1041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ssize_t *index) {
1042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
1043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
1044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mBufferID == bufferID) {
1046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (index != NULL) {
1047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                *index = i;
1048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
1050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
1054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
1056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10585778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setComponentRole(
1059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        bool isEncoder, const char *mime) {
1060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    struct MimeToRole {
1061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime;
1062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *decoderRole;
1063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *encoderRole;
1064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
1065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const MimeToRole kMimeToRole[] = {
1067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG,
1068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.mp3", "audio_encoder.mp3" },
10692944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
10702944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp1", "audio_encoder.mp1" },
10712944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
10722944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp2", "audio_encoder.mp2" },
1073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_NB,
1074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrnb", "audio_encoder.amrnb" },
1075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_WB,
1076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrwb", "audio_encoder.amrwb" },
1077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AAC,
1078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.aac", "audio_encoder.aac" },
1079729de186450f78c099637e1fce743fe531862c52Andreas Huber        { MEDIA_MIMETYPE_AUDIO_VORBIS,
1080729de186450f78c099637e1fce743fe531862c52Andreas Huber            "audio_decoder.vorbis", "audio_encoder.vorbis" },
1081bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian        { MEDIA_MIMETYPE_AUDIO_OPUS,
1082bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian            "audio_decoder.opus", "audio_encoder.opus" },
1083c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_MLAW,
1084c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" },
1085c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_ALAW,
1086c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711alaw", "audio_encoder.g711alaw" },
1087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_AVC,
1088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.avc", "video_encoder.avc" },
10892472b1c0d63454e5d90a982bd6c555de6c3127bdRachad        { MEDIA_MIMETYPE_VIDEO_HEVC,
10902472b1c0d63454e5d90a982bd6c555de6c3127bdRachad            "video_decoder.hevc", "video_encoder.hevc" },
1091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_MPEG4,
1092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.mpeg4", "video_encoder.mpeg4" },
1093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_H263,
1094f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.h263", "video_encoder.h263" },
109594705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP8,
109694705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp8", "video_encoder.vp8" },
109794705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP9,
109894705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp9", "video_encoder.vp9" },
1099ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        { MEDIA_MIMETYPE_AUDIO_RAW,
1100ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            "audio_decoder.raw", "audio_encoder.raw" },
11012f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        { MEDIA_MIMETYPE_AUDIO_FLAC,
11022f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            "audio_decoder.flac", "audio_encoder.flac" },
1103ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        { MEDIA_MIMETYPE_AUDIO_MSGSM,
1104ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen            "audio_decoder.gsm", "audio_encoder.gsm" },
1105774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu        { MEDIA_MIMETYPE_VIDEO_MPEG2,
1106774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu            "video_decoder.mpeg2", "video_encoder.mpeg2" },
110797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        { MEDIA_MIMETYPE_AUDIO_AC3,
110897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            "audio_decoder.ac3", "audio_encoder.ac3" },
11098a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        { MEDIA_MIMETYPE_AUDIO_EAC3,
11108a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            "audio_decoder.eac3", "audio_encoder.eac3" },
1111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
1112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const size_t kNumMimeToRole =
1114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
1115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    size_t i;
1117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (i = 0; i < kNumMimeToRole; ++i) {
1118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcasecmp(mime, kMimeToRole[i].mime)) {
1119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (i == kNumMimeToRole) {
11245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_UNSUPPORTED;
1125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    const char *role =
1128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        isEncoder ? kMimeToRole[i].encoderRole
1129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                  : kMimeToRole[i].decoderRole;
1130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (role != NULL) {
1132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_PARAM_COMPONENTROLETYPE roleParams;
1133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        InitOMXParams(&roleParams);
1134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        strncpy((char *)roleParams.cRole,
1136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                role, OMX_MAX_STRINGNAME_SIZE - 1);
1137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
1139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->setParameter(
1141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamStandardComponentRole,
1142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &roleParams, sizeof(roleParams));
1143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
11455ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("[%s] Failed to set standard component role '%s'.",
1146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 mComponentName.c_str(), role);
11475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
1149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
11515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
1153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
11555778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::configureCodec(
1156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime, const sp<AMessage> &msg) {
11575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t encoder;
11585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("encoder", &encoder)) {
11595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        encoder = false;
11605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1162e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    sp<AMessage> inputFormat = new AMessage();
11634e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    sp<AMessage> outputFormat = mNotify->dup(); // will use this for kWhatOutputFormatChanged
1164e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
11655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mIsEncoder = encoder;
1166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
11675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setComponentRole(encoder /* isEncoder */, mime);
11685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
11705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
11715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
11725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitRate = 0;
11742f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    // FLAC encoder doesn't need a bitrate, other encoders do
11752f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
11762f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            && !msg->findInt32("bitrate", &bitRate)) {
11775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
11785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
11795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1180d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    int32_t storeMeta;
1181d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (encoder
1182d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && msg->findInt32("store-metadata-in-buffers", &storeMeta)
1183d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && storeMeta != 0) {
1184d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE);
1185d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1186d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (err != OK) {
1187308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              ALOGE("[%s] storeMetaDataInBuffers (input) failed w/ err %d",
1188308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    mComponentName.c_str(), err);
1189d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1190308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              return err;
1191308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang          }
1192308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang      }
1193d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1194308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t prependSPSPPS = 0;
11953a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    if (encoder
11963a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
11973a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && prependSPSPPS != 0) {
11983a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        OMX_INDEXTYPE index;
11993a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        err = mOMX->getExtensionIndex(
12003a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                mNode,
12013a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                "OMX.google.android.index.prependSPSPPSToIDRFrames",
12023a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                &index);
12033a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
12043a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err == OK) {
12053a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            PrependSPSPPSToIDRFramesParams params;
12063a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            InitOMXParams(&params);
12073a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            params.bEnable = OMX_TRUE;
12083a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
12093a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            err = mOMX->setParameter(
12103a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                    mNode, index, &params, sizeof(params));
12113a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
12123a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
12133a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err != OK) {
12143a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            ALOGE("Encoder could not be configured to emit SPS/PPS before "
12153a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                  "IDR frames. (err %d)", err);
12163a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
12173a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            return err;
12183a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
12193a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    }
12203a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
1221308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // Only enable metadata mode on encoder output if encoder can prepend
1222308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // sps/pps to idr frames, since in metadata mode the bitstream is in an
1223308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // opaque handle, to which we don't have access.
1224308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t video = !strncasecmp(mime, "video/", 6);
1225308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (encoder && video) {
1226308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS
1227308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && msg->findInt32("store-metadata-in-buffers-output", &storeMeta)
1228308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && storeMeta != 0);
1229308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1230308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, enable);
1231308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1232308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        if (err != OK) {
1233308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            ALOGE("[%s] storeMetaDataInBuffers (output) failed w/ err %d",
1234308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                mComponentName.c_str(), err);
1235308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = 0;
1236308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        } else {
1237308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = enable;
1238308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        }
1239a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
1240a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (!msg->findInt64(
1241a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    "repeat-previous-frame-after",
1242a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    &mRepeatFrameDelayUs)) {
1243a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            mRepeatFrameDelayUs = -1ll;
1244a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
124594ee4b708acfa941581160b267afb79192b1d816Chong Zhang
124694ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (!msg->findInt64("max-pts-gap-to-encoder", &mMaxPtsGapUs)) {
12472c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mMaxPtsGapUs = -1ll;
12482c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
12492c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
12502c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (!msg->findInt64("time-lapse", &mTimePerCaptureUs)) {
12512c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mTimePerCaptureUs = -1ll;
125294ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
125372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
125472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (!msg->findInt32(
125572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    "create-input-buffers-suspended",
125672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    (int32_t*)&mCreateInputBuffersSuspended)) {
125772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mCreateInputBuffersSuspended = false;
125872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
1259308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    }
1260308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1261054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    sp<RefBase> obj;
1262054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    int32_t haveNativeWindow = msg->findObject("native-window", &obj) &&
12635a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        obj != NULL;
1264054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mStoreMetaDataInOutputBuffers = false;
1265e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if (video && !encoder) {
1266e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        inputFormat->setInt32("adaptive-playback", false);
12671713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang
12681713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        int32_t usageProtected;
12691713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        if (msg->findInt32("protected", &usageProtected) && usageProtected) {
12701713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            if (!haveNativeWindow) {
12711713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang                ALOGE("protected output buffers must be sent to an ANativeWindow");
12721713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang                return PERMISSION_DENIED;
12731713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            }
12741713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            mFlags |= kFlagIsGrallocUsageProtected;
12751713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
12761713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        }
1277e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
1278054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (!encoder && video && haveNativeWindow) {
12795a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        sp<NativeWindowWrapper> windowWrapper(
12805a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                static_cast<NativeWindowWrapper *>(obj.get()));
12815a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        sp<ANativeWindow> nativeWindow = windowWrapper->getNativeWindow();
12825a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
12836597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        // START of temporary support for automatic FRC - THIS WILL BE REMOVED
12846597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        int32_t autoFrc;
12856597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        if (msg->findInt32("auto-frc", &autoFrc)) {
12866597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            bool enabled = autoFrc;
12876597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            OMX_CONFIG_BOOLEANTYPE config;
12886597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            InitOMXParams(&config);
12896597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            config.bEnabled = (OMX_BOOL)enabled;
12906597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            status_t temp = mOMX->setConfig(
12916597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                    mNode, (OMX_INDEXTYPE)OMX_IndexConfigAutoFramerateConversion,
12926597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                    &config, sizeof(config));
12936597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            if (temp == OK) {
12946597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                outputFormat->setInt32("auto-frc", enabled);
12956597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            } else if (enabled) {
12966597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                ALOGI("codec does not support requested auto-frc (err %d)", temp);
12976597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            }
12986597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        }
12996597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        // END of temporary support for automatic FRC
13006597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar
13015a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        int32_t tunneled;
13025a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        if (msg->findInt32("feature-tunneled-playback", &tunneled) &&
13035a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            tunneled != 0) {
13045a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            ALOGI("Configuring TUNNELED video playback.");
1305ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            mTunneled = true;
13065a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
130797827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad            int32_t audioHwSync = 0;
130897827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad            if (!msg->findInt32("audio-hw-sync", &audioHwSync)) {
13095a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGW("No Audio HW Sync provided for video tunnel");
13105a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            }
13115a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            err = configureTunneledVideoPlayback(audioHwSync, nativeWindow);
13125a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (err != OK) {
131397827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad                ALOGE("configureTunneledVideoPlayback(%d,%p) failed!",
13145a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        audioHwSync, nativeWindow.get());
13155a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                return err;
1316fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
1317fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1318d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            int32_t maxWidth = 0, maxHeight = 0;
1319d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            if (msg->findInt32("max-width", &maxWidth) &&
1320d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    msg->findInt32("max-height", &maxHeight)) {
1321d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad
1322d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                err = mOMX->prepareForAdaptivePlayback(
1323d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                        mNode, kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight);
1324d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                if (err != OK) {
1325d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    ALOGW("[%s] prepareForAdaptivePlayback failed w/ err %d",
1326d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                            mComponentName.c_str(), err);
1327d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                } else {
1328d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("max-width", maxWidth);
1329d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("max-height", maxHeight);
1330d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("adaptive-playback", true);
1331d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                }
1332d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            }
13335a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        } else {
1334ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            ALOGV("Configuring CPU controlled video playback.");
1335ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            mTunneled = false;
1336ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
13373fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // Explicity reset the sideband handle of the window for
13383fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // non-tunneled video in case the window was previously used
13393fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // for a tunneled video playback.
13403fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            err = native_window_set_sideband_stream(nativeWindow.get(), NULL);
13413fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            if (err != OK) {
13423fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad                ALOGE("set_sideband_stream(NULL) failed! (err %d).", err);
13433fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad                return err;
13443fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            }
13453fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad
13465a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            // Always try to enable dynamic output buffers on native surface
13475a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            err = mOMX->storeMetaDataInBuffers(
13485a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    mNode, kPortIndexOutput, OMX_TRUE);
13495a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (err != OK) {
13505a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d",
1351fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        mComponentName.c_str(), err);
1352e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
13535a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // if adaptive playback has been requested, try JB fallback
13545a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // NOTE: THIS FALLBACK MECHANISM WILL BE REMOVED DUE TO ITS
13555a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // LARGE MEMORY REQUIREMENT
13565a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
13575a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // we will not do adaptive playback on software accessed
13585a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // surfaces as they never had to respond to changes in the
13595a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // crop window, and we don't trust that they will be able to.
13605a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                int usageBits = 0;
13615a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                bool canDoAdaptivePlayback;
13625a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
13635a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                if (nativeWindow->query(
13645a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        nativeWindow.get(),
13655a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        NATIVE_WINDOW_CONSUMER_USAGE_BITS,
13665a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        &usageBits) != OK) {
13675a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    canDoAdaptivePlayback = false;
13685a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                } else {
13695a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    canDoAdaptivePlayback =
13705a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        (usageBits &
13715a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                                (GRALLOC_USAGE_SW_READ_MASK |
13725a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                                 GRALLOC_USAGE_SW_WRITE_MASK)) == 0;
13735a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                }
13745a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
13755a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                int32_t maxWidth = 0, maxHeight = 0;
13765a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                if (canDoAdaptivePlayback &&
13775a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        msg->findInt32("max-width", &maxWidth) &&
13785a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        msg->findInt32("max-height", &maxHeight)) {
13795a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    ALOGV("[%s] prepareForAdaptivePlayback(%dx%d)",
13805a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mComponentName.c_str(), maxWidth, maxHeight);
13815a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
13825a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    err = mOMX->prepareForAdaptivePlayback(
13835a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mNode, kPortIndexOutput, OMX_TRUE, maxWidth,
13845a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            maxHeight);
13855a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    ALOGW_IF(err != OK,
13865a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            "[%s] prepareForAdaptivePlayback failed w/ err %d",
13875a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mComponentName.c_str(), err);
13885a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
13895a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    if (err == OK) {
13905a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("max-width", maxWidth);
13915a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("max-height", maxHeight);
13925a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("adaptive-playback", true);
13935a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    }
1394e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
13955a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // allow failure
13965a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                err = OK;
13975a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            } else {
13985a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGV("[%s] storeMetaDataInBuffers succeeded",
13995a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        mComponentName.c_str());
14005a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                mStoreMetaDataInOutputBuffers = true;
14015a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                inputFormat->setInt32("adaptive-playback", true);
1402fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
14030167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber
14045a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            int32_t push;
14055a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (msg->findInt32("push-blank-buffers-on-shutdown", &push)
14065a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    && push != 0) {
14075a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
14085a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            }
14090167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        }
1410e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang
1411e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        int32_t rotationDegrees;
1412e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        if (msg->findInt32("rotation-degrees", &rotationDegrees)) {
1413e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            mRotationDegrees = rotationDegrees;
1414e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        } else {
1415e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            mRotationDegrees = 0;
1416e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        }
1417054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1418054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1419308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (video) {
14205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (encoder) {
14215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupVideoEncoder(mime, msg);
14225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
142389869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            err = setupVideoDecoder(mime, msg);
14245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
142542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
142642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        int32_t numChannels, sampleRate;
142742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        if (!msg->findInt32("channel-count", &numChannels)
142842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
142942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // Since we did not always check for these, leave them optional
143042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // and have the decoder figure it all out.
143142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = OK;
143242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        } else {
143342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = setupRawAudioFormat(
143442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    encoder ? kPortIndexInput : kPortIndexOutput,
143542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    sampleRate,
143642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    numChannels);
143742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        }
1438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
1439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t numChannels, sampleRate;
14405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)
14415778822d86b0337407514b9372562b86edfa91cdAndreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
14425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
14435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
1444aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            int32_t isADTS, aacProfile;
1445b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            int32_t sbrMode;
14468045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            int32_t maxOutputChannelCount;
14472965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            int32_t pcmLimiterEnable;
14488045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            drcParams_t drc;
1449ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            if (!msg->findInt32("is-adts", &isADTS)) {
1450ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                isADTS = 0;
1451ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
1452aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (!msg->findInt32("aac-profile", &aacProfile)) {
1453aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                aacProfile = OMX_AUDIO_AACObjectNull;
1454aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
1455b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            if (!msg->findInt32("aac-sbr-mode", &sbrMode)) {
1456b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                sbrMode = -1;
1457b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            }
1458ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
14598045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-max-output-channel_count", &maxOutputChannelCount)) {
14608045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                maxOutputChannelCount = -1;
14618045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
14622965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            if (!msg->findInt32("aac-pcm-limiter-enable", &pcmLimiterEnable)) {
14632965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                // value is unknown
14642965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                pcmLimiterEnable = -1;
14652965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            }
14668045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-encoded-target-level", &drc.encodedTargetLevel)) {
14678045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
14688045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.encodedTargetLevel = -1;
14698045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
14708045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-cut-level", &drc.drcCut)) {
14718045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
14728045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.drcCut = -1;
14738045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
14748045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-boost-level", &drc.drcBoost)) {
14758045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
14768045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.drcBoost = -1;
14778045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
14788045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-heavy-compression", &drc.heavyCompression)) {
14798045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
14808045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.heavyCompression = -1;
14818045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
14828045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-target-ref-level", &drc.targetRefLevel)) {
14838045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
14848045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.targetRefLevel = -1;
14858045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
14868045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi
1487ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            err = setupAACCodec(
14884471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    encoder, numChannels, sampleRate, bitRate, aacProfile,
14892965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                    isADTS != 0, sbrMode, maxOutputChannelCount, drc,
14902965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                    pcmLimiterEnable);
14915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
1492729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
14935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
1494729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
14955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
1496729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
1497729de186450f78c099637e1fce743fe531862c52Andreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
1498729de186450f78c099637e1fce743fe531862c52Andreas Huber        // These are PCM-like formats with a fixed sample rate but
1499729de186450f78c099637e1fce743fe531862c52Andreas Huber        // a variable number of channels.
1500729de186450f78c099637e1fce743fe531862c52Andreas Huber
1501729de186450f78c099637e1fce743fe531862c52Andreas Huber        int32_t numChannels;
15025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)) {
15035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
15045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
15055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupG711Codec(encoder, numChannels);
15065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15072f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
15082f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        int32_t numChannels, sampleRate, compressionLevel = -1;
15092f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (encoder &&
15102f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                (!msg->findInt32("channel-count", &numChannels)
15112f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                        || !msg->findInt32("sample-rate", &sampleRate))) {
15122f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("missing channel count or sample rate for FLAC encoder");
15132f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            err = INVALID_OPERATION;
15142f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        } else {
15152f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            if (encoder) {
1516516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                if (!msg->findInt32(
1517cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                            "complexity", &compressionLevel) &&
1518cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                    !msg->findInt32(
1519516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                            "flac-compression-level", &compressionLevel)) {
1520cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                    compressionLevel = 5; // default FLAC compression level
15212f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel < 0) {
1522516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1523516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 0",
1524516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
15252f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 0;
15262f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel > 8) {
1527516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1528516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 8",
1529516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
15302f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 8;
15312f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                }
15322f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            }
1533516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            err = setupFlacCodec(
1534516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    encoder, numChannels, sampleRate, compressionLevel);
15352f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
1536ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
1537ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        int32_t numChannels, sampleRate;
1538ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        if (encoder
1539ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("channel-count", &numChannels)
1540ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
1541ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = INVALID_OPERATION;
1542ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        } else {
1543ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
1544ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        }
154597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AC3)) {
154697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t numChannels;
154797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t sampleRate;
154897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        if (!msg->findInt32("channel-count", &numChannels)
154997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                || !msg->findInt32("sample-rate", &sampleRate)) {
155097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = INVALID_OPERATION;
155197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        } else {
155297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = setupAC3Codec(encoder, numChannels, sampleRate);
155397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        }
15548a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_EAC3)) {
15558a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        int32_t numChannels;
15568a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        int32_t sampleRate;
15578a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        if (!msg->findInt32("channel-count", &numChannels)
15588a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                || !msg->findInt32("sample-rate", &sampleRate)) {
15598a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            err = INVALID_OPERATION;
15608a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        } else {
15618a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            err = setupEAC3Codec(encoder, numChannels, sampleRate);
15628a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        }
15635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1564729de186450f78c099637e1fce743fe531862c52Andreas Huber
15654471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    if (err != OK) {
15664471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber        return err;
15674471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    }
15684471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber
15698b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
15708b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderDelay = 0;
15718b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
15729806555d3930be43e11106281dee354820ac1c88Andreas Huber
15738b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
15748b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderPadding = 0;
15758b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
15768b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen
15779806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (msg->findInt32("channel-mask", &mChannelMask)) {
15789806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = true;
15799806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else {
15809806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = false;
15819806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
15829806555d3930be43e11106281dee354820ac1c88Andreas Huber
1583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t maxInputSize;
1584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (msg->findInt32("max-input-size", &maxInputSize)) {
15855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
1586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
15875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
1588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
15895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15904e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    mBaseOutputFormat = outputFormat;
15914e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar
1592e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ(getPortFormat(kPortIndexInput, inputFormat), (status_t)OK);
1593e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ(getPortFormat(kPortIndexOutput, outputFormat), (status_t)OK);
1594e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mInputFormat = inputFormat;
1595e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mOutputFormat = outputFormat;
1596e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
15975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
1598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1600f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
1601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
1603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
1604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (def.nBufferSize >= size) {
1613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
1614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nBufferSize = size;
1617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
1619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->getParameter(
1626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(def.nBufferSize >= size);
1633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
16375778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::selectAudioPortFormat(
16385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
16395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_AUDIO_PARAM_PORTFORMATTYPE format;
16405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&format);
16415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    format.nPortIndex = portIndex;
16435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (OMX_U32 index = 0;; ++index) {
16445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        format.nIndex = index;
16455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
16475778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioPortFormat,
16485778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &format, sizeof(format));
16495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
16515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
16525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (format.eEncoding == desiredFormat) {
16555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
16565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
16605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format));
16615778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
16625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16635778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAACCodec(
1664aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        bool encoder, int32_t numChannels, int32_t sampleRate,
16658045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        int32_t bitRate, int32_t aacProfile, bool isADTS, int32_t sbrMode,
16662965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang        int32_t maxOutputChannelCount, const drcParams_t& drc,
16672965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang        int32_t pcmLimiterEnable) {
1668ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (encoder && isADTS) {
1669ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return -EINVAL;
1670ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
1671ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
16725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setupRawAudioFormat(
16735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
16745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sampleRate,
16755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            numChannels);
16765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
16785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
16795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (encoder) {
16825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
16835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
16855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
16865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
16895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
16905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = kPortIndexOutput;
16915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
16935778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
16945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
16965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
16975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.bFlagErrorConcealment = OMX_TRUE;
17005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
17015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
17035778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
17045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
17065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
17075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
17105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&profile);
17115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nPortIndex = kPortIndexOutput;
17125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
17145778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
17155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
17175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
17185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nChannels = numChannels;
17215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eChannelMode =
17235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (numChannels == 1)
17245778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
17255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nSampleRate = sampleRate;
17275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nBitRate = bitRate;
17285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAudioBandWidth = 0;
17295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nFrameLength = 0;
17305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACtools = OMX_AUDIO_AACToolAll;
17315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACERtools = OMX_AUDIO_AACERNone;
1732aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
17335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
1734b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        switch (sbrMode) {
1735b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 0:
1736b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // disable sbr
1737b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
1738b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
1739b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
1740b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 1:
1741b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable single-rate sbr
1742b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
1743b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
1744b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
1745b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 2:
1746b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable dual-rate sbr
1747b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
1748b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
1749b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
1750b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case -1:
1751b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable both modes -> the codec will decide which mode should be used
1752b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
1753b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
1754b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
1755b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        default:
1756b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // unsupported sbr mode
1757b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            return BAD_VALUE;
1758b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        }
1759b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi
17605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
17625778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
17635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
17655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
17665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
17695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_AUDIO_PARAM_AACPROFILETYPE profile;
1772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&profile);
1773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nPortIndex = kPortIndexInput;
1774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
17755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
1776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
1777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nChannels = numChannels;
1783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nSampleRate = sampleRate;
1784ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1785ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    profile.eAACStreamFormat =
1786ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        isADTS
1787ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            ? OMX_AUDIO_AACStreamFormatMP4ADTS
1788ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            : OMX_AUDIO_AACStreamFormatMP4FF;
1789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
17908045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    OMX_AUDIO_PARAM_ANDROID_AACPRESENTATIONTYPE presentation;
17918045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nMaxOutputChannels = maxOutputChannelCount;
17928045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nDrcCut = drc.drcCut;
17938045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nDrcBoost = drc.drcBoost;
17948045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nHeavyCompression = drc.heavyCompression;
17958045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nTargetReferenceLevel = drc.targetRefLevel;
17968045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nEncodedTargetLevel = drc.encodedTargetLevel;
17972965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang    presentation.nPCMLimiterEnable = pcmLimiterEnable;
17988045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi
17998045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    status_t res = mOMX->setParameter(mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
18008045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    if (res == OK) {
18018045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        // optional parameters, will not cause configuration failure
18028045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        mOMX->setParameter(mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAacPresentation,
18038045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                &presentation, sizeof(presentation));
18048045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    } else {
18058045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        ALOGW("did not set AudioAndroidAacPresentation due to error %d when setting AudioAac", res);
18068045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    }
18078045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    return res;
18085778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
181097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryustatus_t ACodec::setupAC3Codec(
181197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        bool encoder, int32_t numChannels, int32_t sampleRate) {
181297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    status_t err = setupRawAudioFormat(
181397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
181497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
181597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
181697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
181797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
181897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
181997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (encoder) {
182097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        ALOGW("AC3 encoding is not supported.");
182197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return INVALID_OPERATION;
182297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
182397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
182497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    OMX_AUDIO_PARAM_ANDROID_AC3TYPE def;
182597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    InitOMXParams(&def);
182697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nPortIndex = kPortIndexInput;
182797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
182897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    err = mOMX->getParameter(
182997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
183097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
183197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
183297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
183397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
183497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
183597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
183697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
183797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
183897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nChannels = numChannels;
183997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nSampleRate = sampleRate;
184097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
184197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    return mOMX->setParameter(
184297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
184397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
184497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
184597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
184697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu}
184797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
18488a4728966dc9c78e21c3c93a927707e93c05e5e0Rachadstatus_t ACodec::setupEAC3Codec(
18498a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        bool encoder, int32_t numChannels, int32_t sampleRate) {
18508a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    status_t err = setupRawAudioFormat(
18518a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
18528a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
18538a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (err != OK) {
18548a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return err;
18558a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
18568a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
18578a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (encoder) {
18588a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        ALOGW("EAC3 encoding is not supported.");
18598a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return INVALID_OPERATION;
18608a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
18618a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
18628a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    OMX_AUDIO_PARAM_ANDROID_EAC3TYPE def;
18638a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    InitOMXParams(&def);
18648a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nPortIndex = kPortIndexInput;
18658a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
18668a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    err = mOMX->getParameter(
18678a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            mNode,
18688a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
18698a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            &def,
18708a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            sizeof(def));
18718a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
18728a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (err != OK) {
18738a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return err;
18748a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
18758a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
18768a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nChannels = numChannels;
18778a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nSampleRate = sampleRate;
18788a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
18798a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    return mOMX->setParameter(
18808a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            mNode,
18818a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
18828a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            &def,
18838a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            sizeof(def));
18848a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad}
18858a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
18865778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
18875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        bool isAMRWB, int32_t bps) {
18885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (isAMRWB) {
18895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 6600) {
18905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB0;
18915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 8850) {
18925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB1;
18935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 12650) {
18945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB2;
18955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 14250) {
18965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB3;
18975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 15850) {
18985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB4;
18995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 18250) {
19005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB5;
19015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 19850) {
19025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB6;
19035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 23050) {
19045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB7;
19055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 23850 bps
19085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeWB8;
19095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {  // AMRNB
19105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 4750) {
19115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB0;
19125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5150) {
19135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB1;
19145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5900) {
19155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB2;
19165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 6700) {
19175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB3;
19185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7400) {
19195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB4;
19205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7950) {
19215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB5;
19225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 10200) {
19235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB6;
19245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 12200 bps
19275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeNB7;
19285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
19315778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
1932729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_AMRTYPE def;
1933729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
19345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
1935729de186450f78c099637e1fce743fe531862c52Andreas Huber
1936729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err =
1937729de186450f78c099637e1fce743fe531862c52Andreas Huber        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1938729de186450f78c099637e1fce743fe531862c52Andreas Huber
1939729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1940729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1941729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1942729de186450f78c099637e1fce743fe531862c52Andreas Huber
1943729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
19445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
19455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
19475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1948729de186450f78c099637e1fce743fe531862c52Andreas Huber
19495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1952729de186450f78c099637e1fce743fe531862c52Andreas Huber
19535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupRawAudioFormat(
19545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
19555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            isWAMR ? 16000 : 8000 /* sampleRate */,
19565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            1 /* numChannels */);
1957729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1958729de186450f78c099637e1fce743fe531862c52Andreas Huber
19595778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupG711Codec(bool encoder, int32_t numChannels) {
19605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(!encoder);  // XXX TODO
19615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1962729de186450f78c099637e1fce743fe531862c52Andreas Huber    return setupRawAudioFormat(
1963729de186450f78c099637e1fce743fe531862c52Andreas Huber            kPortIndexInput, 8000 /* sampleRate */, numChannels);
1964729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1965729de186450f78c099637e1fce743fe531862c52Andreas Huber
19662f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivistatus_t ACodec::setupFlacCodec(
19672f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
19682f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
19692f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder) {
19702f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        OMX_AUDIO_PARAM_FLACTYPE def;
19712f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        InitOMXParams(&def);
19722f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nPortIndex = kPortIndexOutput;
19732f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
19742f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        // configure compression level
19752f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        status_t err = mOMX->getParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
19762f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
19772f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
19782f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
19792f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
19802f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nCompressionLevel = compressionLevel;
19812f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        err = mOMX->setParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
19822f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
19832f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
19842f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
19852f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
19862f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
19872f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
19882f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    return setupRawAudioFormat(
19892f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            encoder ? kPortIndexInput : kPortIndexOutput,
19902f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            sampleRate,
19912f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            numChannels);
19922f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi}
19932f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
1994729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t ACodec::setupRawAudioFormat(
1995729de186450f78c099637e1fce743fe531862c52Andreas Huber        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
1996729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1997729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
1998729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.nPortIndex = portIndex;
1999729de186450f78c099637e1fce743fe531862c52Andreas Huber
2000729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err = mOMX->getParameter(
2001729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2002729de186450f78c099637e1fce743fe531862c52Andreas Huber
2003729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2004729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2005729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2006729de186450f78c099637e1fce743fe531862c52Andreas Huber
2007729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
2008729de186450f78c099637e1fce743fe531862c52Andreas Huber
2009729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->setParameter(
2010729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2011729de186450f78c099637e1fce743fe531862c52Andreas Huber
2012729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2013729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2014729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2015729de186450f78c099637e1fce743fe531862c52Andreas Huber
2016729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
2017729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&pcmParams);
2018729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nPortIndex = portIndex;
2019729de186450f78c099637e1fce743fe531862c52Andreas Huber
2020729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->getParameter(
2021729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
2022729de186450f78c099637e1fce743fe531862c52Andreas Huber
2023729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2024729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2025729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2026729de186450f78c099637e1fce743fe531862c52Andreas Huber
2027729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nChannels = numChannels;
2028729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.eNumData = OMX_NumericalDataSigned;
2029729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.bInterleaved = OMX_TRUE;
2030729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nBitPerSample = 16;
2031729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nSamplingRate = sampleRate;
2032729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
2033729de186450f78c099637e1fce743fe531862c52Andreas Huber
2034c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber    if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
2035c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber        return OMX_ErrorNone;
2036729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2037729de186450f78c099637e1fce743fe531862c52Andreas Huber
2038729de186450f78c099637e1fce743fe531862c52Andreas Huber    return mOMX->setParameter(
2039729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
2040729de186450f78c099637e1fce743fe531862c52Andreas Huber}
2041729de186450f78c099637e1fce743fe531862c52Andreas Huber
20425a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachadstatus_t ACodec::configureTunneledVideoPlayback(
204397827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad        int32_t audioHwSync, const sp<ANativeWindow> &nativeWindow) {
20445a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    native_handle_t* sidebandHandle;
20455a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
20465a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    status_t err = mOMX->configureVideoTunnelMode(
20475a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            mNode, kPortIndexOutput, OMX_TRUE, audioHwSync, &sidebandHandle);
20485a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    if (err != OK) {
20495a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        ALOGE("configureVideoTunnelMode failed! (err %d).", err);
20505a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        return err;
20515a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    }
20525a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
20535a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    err = native_window_set_sideband_stream(nativeWindow.get(), sidebandHandle);
20545a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    if (err != OK) {
20555a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        ALOGE("native_window_set_sideband_stream(%p) failed! (err %d).",
20565a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                sidebandHandle, err);
20575a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        return err;
20585a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    }
20595a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
20605a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    return OK;
20615a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad}
20625a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
2063f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoPortFormatType(
2064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
2065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_VIDEO_CODINGTYPE compressionFormat,
2066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_COLOR_FORMATTYPE colorFormat) {
2067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
2068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
2069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = portIndex;
2070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
2071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool found = false;
2072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 index = 0;
2074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (;;) {
2075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        format.nIndex = index;
2076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->getParameter(
2077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamVideoPortFormat,
2078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &format, sizeof(format));
2079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
2081f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return err;
2082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2084229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        // substitute back flexible color format to codec supported format
2085229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        OMX_U32 flexibleEquivalent;
2086229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        if (compressionFormat == OMX_VIDEO_CodingUnused &&
2087229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                isFlexibleColorFormat(
2088229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                        mOMX, mNode, format.eColorFormat, &flexibleEquivalent) &&
2089229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                colorFormat == flexibleEquivalent) {
2090229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            ALOGI("[%s] using color format %#x in place of %#x",
2091229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                    mComponentName.c_str(), format.eColorFormat, colorFormat);
2092229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            colorFormat = format.eColorFormat;
2093229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
2094229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
2095f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The following assertion is violated by TI's video decoder.
2096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // CHECK_EQ(format.nIndex, index);
2097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
2099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexInput
2100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && colorFormat == format.eColorFormat) {
2101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eCompressionFormat does not seem right.
2102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
2103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
2104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexOutput
2106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && compressionFormat == format.eCompressionFormat) {
2107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eColorFormat does not seem right.
2108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
2109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
2110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (format.eCompressionFormat == compressionFormat
2114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && format.eColorFormat == colorFormat) {
2115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            found = true;
2116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ++index;
2120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!found) {
2123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return UNKNOWN_ERROR;
2124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->setParameter(
2127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
2128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
2129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
2131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2133f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setSupportedOutputFormat() {
2134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
2135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
2136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = kPortIndexOutput;
2137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
2138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
2140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
2141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
2142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
2143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)format.eCompressionFormat, (int)OMX_VIDEO_CodingUnused);
2144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mOMX->setParameter(
2146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
2147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
2148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2150e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic const struct VideoCodingMapEntry {
2151e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    const char *mMime;
2152e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    OMX_VIDEO_CODINGTYPE mVideoCodingType;
2153e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber} kVideoCodingMapEntry[] = {
2154e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC },
21552472b1c0d63454e5d90a982bd6c555de6c3127bdRachad    { MEDIA_MIMETYPE_VIDEO_HEVC, OMX_VIDEO_CodingHEVC },
2156e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 },
2157e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 },
2158e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 },
215994705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 },
216094705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 },
2161e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber};
2162e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
21635778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic status_t GetVideoCodingTypeFromMime(
21645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
2165e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
2166e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
2167e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
2168e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) {
2169e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *codingType = kVideoCodingMapEntry[i].mVideoCodingType;
2170e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
2171e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
2172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2174e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    *codingType = OMX_VIDEO_CodingUnused;
2175e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2176e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
2177e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
2178e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2179e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic status_t GetMimeTypeForVideoCoding(
2180e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        OMX_VIDEO_CODINGTYPE codingType, AString *mime) {
2181e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
2182e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
2183e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
2184e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) {
2185e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *mime = kVideoCodingMapEntry[i].mMime;
2186e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
2187e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
2188e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
2189e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2190e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    mime->clear();
2191e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2192e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
21935778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
21945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21955778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoDecoder(
219689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        const char *mime, const sp<AMessage> &msg) {
219789869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    int32_t width, height;
219889869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    if (!msg->findInt32("width", &width)
219989869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            || !msg->findInt32("height", &height)) {
220089869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        return INVALID_OPERATION;
220189869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    }
220289869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar
22035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
22045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
22055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
2211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
2212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
221789869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    int32_t tmp;
221889869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    if (msg->findInt32("color-format", &tmp)) {
221989869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        OMX_COLOR_FORMATTYPE colorFormat =
222089869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            static_cast<OMX_COLOR_FORMATTYPE>(tmp);
222189869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        err = setVideoPortFormatType(
222289869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar                kPortIndexOutput, OMX_VIDEO_CodingUnused, colorFormat);
222389869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        if (err != OK) {
222489869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            ALOGW("[%s] does not support color format %d",
222589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar                  mComponentName.c_str(), colorFormat);
222689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            err = setSupportedOutputFormat();
222789869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        }
222889869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    } else {
222989869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        err = setSupportedOutputFormat();
223089869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    }
2231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
223678b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    int32_t frameRateInt;
223778b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    float frameRateFloat;
223878b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    if (!msg->findFloat("frame-rate", &frameRateFloat)) {
223978b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        if (!msg->findInt32("frame-rate", &frameRateInt)) {
224078b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            frameRateInt = -1;
224178b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        }
224278b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        frameRateFloat = (float)frameRateInt;
224378b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    }
224478b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad
2245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
224678b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            kPortIndexInput, width, height, compressionFormat, frameRateFloat);
2247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
2253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
2254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
22625778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) {
22635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
22645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("color-format", &tmp)) {
22655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
22665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_COLOR_FORMATTYPE colorFormat =
22695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        static_cast<OMX_COLOR_FORMATTYPE>(tmp);
22705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setVideoPortFormatType(
22725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
22735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support color format %d",
22765778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str(), colorFormat);
22775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Input port configuration */
22825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
22845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&def);
22855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
22875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexInput;
22895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
22915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
22925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t width, height, bitrate;
22985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("width", &width)
22995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("height", &height)
23005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("bitrate", &bitrate)) {
23015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
23025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
23055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
23065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t stride;
23085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("stride", &stride)) {
23095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        stride = width;
23105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nStride = stride;
23135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t sliceHeight;
23155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("slice-height", &sliceHeight)) {
23165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sliceHeight = height;
23175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nSliceHeight = sliceHeight;
23205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
23225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
23245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
23255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
23265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
23275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
23285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
23302c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        mTimePerFrameUs = (int64_t) (1000000.0f / frameRate);
23315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
23345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
2335a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    // this is redundant as it was already set up in setVideoPortFormatType
2336a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    // FIXME for now skip this only for flexible YUV formats
2337a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    if (colorFormat != OMX_COLOR_FormatYUV420Flexible) {
2338a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar        video_def->eColorFormat = colorFormat;
2339a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    }
23405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
23425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
23435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
23455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set input port definition parameters.",
23465778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
23475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
23495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Output port configuration */
23525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
23545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
23555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
23575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
23585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
23615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
23625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
23645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support compression format %d",
23655778822d86b0337407514b9372562b86edfa91cdAndreas Huber             mComponentName.c_str(), compressionFormat);
23665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
23685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexOutput;
23715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
23735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
23745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
23765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
23775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
23805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
23815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = 0;
23825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nBitrate = bitrate;
23835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = compressionFormat;
23845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = OMX_COLOR_FormatUnused;
23855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
23875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
23885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
23905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set output port definition parameters.",
23915778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
23925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
23945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (compressionFormat) {
23975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingMPEG4:
23985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupMPEG4EncoderParameters(msg);
23995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
24005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingH263:
24025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupH263EncoderParameters(msg);
24035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
24045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingAVC:
24065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupAVCEncoderParameters(msg);
24075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
24085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2409c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        case OMX_VIDEO_CodingHEVC:
2410c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            err = setupHEVCEncoderParameters(msg);
2411c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            break;
2412c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
241389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP8:
241489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP9:
241589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            err = setupVPXEncoderParameters(msg);
241689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            break;
241789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
24185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
24195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
24205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGI("setupVideoEncoder succeeded");
24235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
24255778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
24265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24270dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dongstatus_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) {
24280dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    OMX_VIDEO_PARAM_INTRAREFRESHTYPE params;
24290dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    InitOMXParams(&params);
24300dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.nPortIndex = kPortIndexOutput;
24310dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
24320dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode);
24330dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
24340dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic ||
24350dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
24360dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
24370dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) {
24380dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
24390dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
24400dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nCirMBs = mbs;
24410dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
24420dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
24430dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive ||
24440dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
24450dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
24460dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) {
24470dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
24480dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
24490dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirMBs = mbs;
24500dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
24510dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t ref;
24520dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) {
24530dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
24540dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
24550dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirRef = ref;
24560dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
24570dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
24580dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = mOMX->setParameter(
24590dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            mNode, OMX_IndexParamVideoIntraRefresh,
24600dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            &params, sizeof(params));
24610dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    return err;
24620dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong}
24630dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
24645778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
24655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (iFramesInterval < 0) {
24665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0xFFFFFFFF;
24675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (iFramesInterval == 0) {
24685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0;
24695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_U32 ret = frameRate * iFramesInterval;
24715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return ret;
24725778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
24735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
247496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatic OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) {
247596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    int32_t tmp;
247696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    if (!msg->findInt32("bitrate-mode", &tmp)) {
247796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        return OMX_Video_ControlRateVariable;
247896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    }
247996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
248096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp);
248196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber}
248296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
24835778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
24845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
24855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
24865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
24875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
24885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
249096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
249196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
24925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
24935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
24945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
24955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
24965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
24975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
24985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
24995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
25025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&mpeg4type);
25035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPortIndex = kPortIndexOutput;
25045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
25065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
25075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
25095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
25105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nSliceHeaderSpacing = 0;
25135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bSVH = OMX_FALSE;
25145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bGov = OMX_FALSE;
25155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nAllowedPictureTypes =
25175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
25185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
25205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mpeg4type.nPFrames == 0) {
25215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
25225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nBFrames = 0;
25245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nIDCVLCThreshold = 0;
25255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bACPred = OMX_TRUE;
25265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nMaxPacketSize = 256;
25275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nTimeIncRes = 1000;
25285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nHeaderExtension = 0;
25295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bReversibleVLC = OMX_FALSE;
25305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
25325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
25335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
25345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
25355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
25365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
25375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
25395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
25415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
25425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
25435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
25455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
25465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
25495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
25505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
25525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
25535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
255596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
25565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
25585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
25595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
25625778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
25635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25645778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
25655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
25665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
25675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
25685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
25695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
257196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
257296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
25735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
25745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
25755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
25765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
25775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
25785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
25795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
25805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_H263TYPE h263type;
25835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h263type);
25845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPortIndex = kPortIndexOutput;
25855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
25875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
25885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
25905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
25915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nAllowedPictureTypes =
25945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
25955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
25975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h263type.nPFrames == 0) {
25985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
25995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nBFrames = 0;
26015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
26035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
26045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
26055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
26065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
26075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
26085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
26105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
26125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
26135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
26145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
26165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
26175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bPLUSPTYPEAllowed = OMX_FALSE;
26205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bForceRoundingTypeToZero = OMX_FALSE;
26215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPictureHeaderRepetition = 0;
26225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nGOBHeaderInterval = 0;
26235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
26255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
26265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
26285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
26295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
263196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
26325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
26345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
26355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
26385778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
26395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2640a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar// static
2641a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnarint /* OMX_VIDEO_AVCLEVELTYPE */ ACodec::getAVCLevelFor(
2642a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        int width, int height, int rate, int bitrate,
2643a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        OMX_VIDEO_AVCPROFILETYPE profile) {
2644a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    // convert bitrate to main/baseline profile kbps equivalent
2645a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    switch (profile) {
2646a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        case OMX_VIDEO_AVCProfileHigh10:
2647a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 3000); break;
2648a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        case OMX_VIDEO_AVCProfileHigh:
2649a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 1250); break;
2650a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        default:
2651a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 1000); break;
2652a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    }
2653a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
2654a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    // convert size and rate to MBs
2655a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    width = divUp(width, 16);
2656a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    height = divUp(height, 16);
2657a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    int mbs = width * height;
2658a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    rate *= mbs;
2659a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    int maxDimension = max(width, height);
2660a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
2661a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    static const int limits[][5] = {
2662a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        /*   MBps     MB   dim  bitrate        level */
2663a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    1485,    99,  28,     64, OMX_VIDEO_AVCLevel1  },
2664a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    1485,    99,  28,    128, OMX_VIDEO_AVCLevel1b },
2665a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    3000,   396,  56,    192, OMX_VIDEO_AVCLevel11 },
2666a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    6000,   396,  56,    384, OMX_VIDEO_AVCLevel12 },
2667a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   11880,   396,  56,    768, OMX_VIDEO_AVCLevel13 },
2668a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   11880,   396,  56,   2000, OMX_VIDEO_AVCLevel2  },
2669a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   19800,   792,  79,   4000, OMX_VIDEO_AVCLevel21 },
2670a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   20250,  1620, 113,   4000, OMX_VIDEO_AVCLevel22 },
2671a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   40500,  1620, 113,  10000, OMX_VIDEO_AVCLevel3  },
2672a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  108000,  3600, 169,  14000, OMX_VIDEO_AVCLevel31 },
2673a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  216000,  5120, 202,  20000, OMX_VIDEO_AVCLevel32 },
2674a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  245760,  8192, 256,  20000, OMX_VIDEO_AVCLevel4  },
2675a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  245760,  8192, 256,  50000, OMX_VIDEO_AVCLevel41 },
2676a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  522240,  8704, 263,  50000, OMX_VIDEO_AVCLevel42 },
2677a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  589824, 22080, 420, 135000, OMX_VIDEO_AVCLevel5  },
2678a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  983040, 36864, 543, 240000, OMX_VIDEO_AVCLevel51 },
2679a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        { 2073600, 36864, 543, 240000, OMX_VIDEO_AVCLevel52 },
2680a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    };
2681a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
2682a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    for (size_t i = 0; i < ARRAY_SIZE(limits); i++) {
2683a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        const int (&limit)[5] = limits[i];
2684a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        if (rate <= limit[0] && mbs <= limit[1] && maxDimension <= limit[2]
2685a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar                && bitrate <= limit[3]) {
2686a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            return limit[4];
2687a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        }
2688a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    }
2689a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    return 0;
2690a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar}
2691a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
26925778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
26935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
26945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
26955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
26965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
26975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
269996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
270096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
27015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
27025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
27035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
27045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
27055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
27065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
27075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
27085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27100dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = OK;
27110dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    int32_t intraRefreshMode = 0;
27120dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) {
27130dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode);
27140dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (err != OK) {
27150dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
27160dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong                    err, intraRefreshMode);
27170dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return err;
27180dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
27190dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
27200dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
27215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_AVCTYPE h264type;
27225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h264type);
27235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nPortIndex = kPortIndexOutput;
27245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27250dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    err = mOMX->getParameter(
27265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
27275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
27295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
27305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nAllowedPictureTypes =
27335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
27345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
27365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
27375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
27385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
27395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
27405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
27415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
27435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
27455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
27465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
27475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
27495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
27505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // XXX
27537c25df82dfc8bbedb58608242f0d923a4594bb14James Dong    if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) {
27547c25df82dfc8bbedb58608242f0d923a4594bb14James Dong        ALOGW("Use baseline profile instead of %d for AVC recording",
27557c25df82dfc8bbedb58608242f0d923a4594bb14James Dong            h264type.eProfile);
27565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
27575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
27605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nSliceHeaderSpacing = 0;
27615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bUseHadamard = OMX_TRUE;
27625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefFrames = 1;
27635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nBFrames = 0;
27645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
27655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (h264type.nPFrames == 0) {
27665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
27675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
27685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx10ActiveMinus1 = 0;
27695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx11ActiveMinus1 = 0;
27705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bEntropyCodingCABAC = OMX_FALSE;
27715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bWeightedPPrediction = OMX_FALSE;
27725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bconstIpred = OMX_FALSE;
27735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirect8x8Inference = OMX_FALSE;
27745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirectSpatialTemporal = OMX_FALSE;
27755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nCabacInitIdc = 0;
27765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.nBFrames != 0) {
27795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
27805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableUEP = OMX_FALSE;
27835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableFMO = OMX_FALSE;
27845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableASO = OMX_FALSE;
27855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableRS = OMX_FALSE;
27865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bFrameMBsOnly = OMX_TRUE;
27875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bMBAFF = OMX_FALSE;
27885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
27895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
27915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
27925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
27945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
27955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
279796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return configureBitrate(bitrate, bitrateMode);
27985778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
27995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2800c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachadstatus_t ACodec::setupHEVCEncoderParameters(const sp<AMessage> &msg) {
2801c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    int32_t bitrate, iFrameInterval;
2802c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findInt32("bitrate", &bitrate)
2803c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
2804c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return INVALID_OPERATION;
2805c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2806c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2807c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
2808c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2809c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    float frameRate;
2810c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findFloat("frame-rate", &frameRate)) {
2811c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t tmp;
2812c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("frame-rate", &tmp)) {
2813c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
2814c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
2815c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        frameRate = (float)tmp;
2816c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2817c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2818c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_PARAM_HEVCTYPE hevcType;
2819c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    InitOMXParams(&hevcType);
2820c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    hevcType.nPortIndex = kPortIndexOutput;
2821c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2822c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    status_t err = OK;
2823c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    err = mOMX->getParameter(
2824c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
2825c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
2826c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
2827c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2828c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2829c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    int32_t profile;
2830c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (msg->findInt32("profile", &profile)) {
2831c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t level;
2832c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("level", &level)) {
2833c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
2834c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
2835c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2836c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        err = verifySupportForProfileAndLevel(profile, level);
2837c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (err != OK) {
2838c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return err;
2839c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
2840c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2841c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eProfile = static_cast<OMX_VIDEO_HEVCPROFILETYPE>(profile);
2842c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eLevel = static_cast<OMX_VIDEO_HEVCLEVELTYPE>(level);
2843c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2844c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2845c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    // TODO: Need OMX structure definition for setting iFrameInterval
2846c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2847c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    err = mOMX->setParameter(
2848c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
2849c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
2850c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
2851c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2852c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2853c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    return configureBitrate(bitrate, bitrateMode);
2854c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad}
2855c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
285689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huberstatus_t ACodec::setupVPXEncoderParameters(const sp<AMessage> &msg) {
285789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    int32_t bitrate;
28584154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    int32_t iFrameInterval = 0;
28594154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    size_t tsLayers = 0;
28604154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE pattern =
28614154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        OMX_VIDEO_VPXTemporalLayerPatternNone;
28624154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    static const uint32_t kVp8LayerRateAlloction
28634154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS]
28644154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS] = {
28654154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        {100, 100, 100},  // 1 layer
28664154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 60, 100, 100},  // 2 layers {60%, 40%}
28674154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 40,  60, 100},  // 3 layers {40%, 20%, 40%}
28684154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    };
286989b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    if (!msg->findInt32("bitrate", &bitrate)) {
287089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        return INVALID_OPERATION;
287189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    }
28724154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    msg->findInt32("i-frame-interval", &iFrameInterval);
287389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
287489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
287589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
28764154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    float frameRate;
28774154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (!msg->findFloat("frame-rate", &frameRate)) {
28784154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        int32_t tmp;
28794154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (!msg->findInt32("frame-rate", &tmp)) {
28804154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            return INVALID_OPERATION;
28814154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
28824154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        frameRate = (float)tmp;
28834154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
28844154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
28854154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    AString tsSchema;
28864154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (msg->findString("ts-schema", &tsSchema)) {
28874154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (tsSchema == "webrtc.vp8.1-layer") {
28884154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
28894154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 1;
28904154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else if (tsSchema == "webrtc.vp8.2-layer") {
28914154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
28924154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 2;
28934154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else if (tsSchema == "webrtc.vp8.3-layer") {
28944154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
28954154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 3;
28964154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else {
28974154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            ALOGW("Unsupported ts-schema [%s]", tsSchema.c_str());
28984154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
28994154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
29004154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
29014154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
29024154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    InitOMXParams(&vp8type);
29034154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    vp8type.nPortIndex = kPortIndexOutput;
29044154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    status_t err = mOMX->getParameter(
29054154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
29064154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            &vp8type, sizeof(vp8type));
29074154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
29084154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (err == OK) {
29094154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (iFrameInterval > 0) {
29104154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nKeyFrameInterval = setPFramesSpacing(iFrameInterval, frameRate);
29114154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
29124154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.eTemporalPattern = pattern;
29134154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.nTemporalLayerCount = tsLayers;
29144154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (tsLayers > 0) {
29154154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            for (size_t i = 0; i < OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS; i++) {
29164154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                vp8type.nTemporalLayerBitrateRatio[i] =
29174154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                    kVp8LayerRateAlloction[tsLayers - 1][i];
29184154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            }
29194154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
29204154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (bitrateMode == OMX_Video_ControlRateConstant) {
29214154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMinQuantizer = 2;
29224154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMaxQuantizer = 63;
29234154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
29244154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
29254154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        err = mOMX->setParameter(
29264154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
29274154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                &vp8type, sizeof(vp8type));
29284154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (err != OK) {
29294154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            ALOGW("Extended VP8 parameters set failed: %d", err);
29304154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
29314154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
29324154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
293389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    return configureBitrate(bitrate, bitrateMode);
293489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber}
293589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
29365778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::verifySupportForProfileAndLevel(
29375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t profile, int32_t level) {
29385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
29395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&params);
29405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    params.nPortIndex = kPortIndexOutput;
29415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (params.nProfileIndex = 0;; ++params.nProfileIndex) {
29435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
29445778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode,
29455778822d86b0337407514b9372562b86edfa91cdAndreas Huber                OMX_IndexParamVideoProfileLevelQuerySupported,
29465778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &params,
29475778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sizeof(params));
29485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
29505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
29515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
29525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
29545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
29555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (profile == supportedProfile && level <= supportedLevel) {
29575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OK;
29585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
29595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29605778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
29615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
296296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatus_t ACodec::configureBitrate(
296396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) {
29645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
29655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&bitrateType);
29665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
29675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
29695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
29705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
29715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
29735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
29745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
297696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    bitrateType.eControlRate = bitrateMode;
29775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nTargetBitrate = bitrate;
29785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
29805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
29815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
29825778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
29835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29845778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupErrorCorrectionParameters() {
29855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
29865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&errorCorrectionType);
29875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nPortIndex = kPortIndexOutput;
29885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
29905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
29915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
29925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
29945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OK;  // Optional feature. Ignore this failure
29955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableHEC = OMX_FALSE;
29985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableResync = OMX_TRUE;
29995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nResynchMarkerSpacing = 256;
30005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
30015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableRVLC = OMX_FALSE;
30025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
30045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
30055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
30065778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
30075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3008f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoFormatOnPort(
3009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
301078b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat,
301178b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        float frameRate) {
3012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
3013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
3014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
3015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
3017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
3019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
3020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
3022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
3024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // XXX Need a (much) better heuristic to compute input buffer sizes.
3025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const size_t X = 64 * 1024;
3026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (def.nBufferSize < X) {
3027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.nBufferSize = X;
3028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
3032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameWidth = width;
3034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameHeight = height;
3035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
3037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eCompressionFormat = compressionFormat;
3038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eColorFormat = OMX_COLOR_FormatUnused;
303978b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        if (frameRate >= 0) {
304078b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
304178b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        }
3042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
3045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
3046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
3048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3050f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::initNativeWindow() {
3051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL) {
3052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
3053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
3056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
3057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3059d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Hubersize_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
3060d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    size_t n = 0;
3061d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
3062d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
3063d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        const BufferInfo &info = mBuffers[portIndex].itemAt(i);
3064d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
3065d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
3066d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            ++n;
3067d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        }
3068d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    }
3069d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
3070d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    return n;
3071d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber}
3072d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
30737e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubersize_t ACodec::countBuffersOwnedByNativeWindow() const {
30747e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    size_t n = 0;
30757e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
30767e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
30777e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
30787e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
30797e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
30807e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            ++n;
30817e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        }
30827e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
30837e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
30847e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    return n;
30857e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
30867e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
30877e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubervoid ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
30887e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (mNativeWindow == NULL) {
30897e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        return;
30907e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
30917e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
3092e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    while (countBuffersOwnedByNativeWindow() > mNumUndequeuedBuffers
30937e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            && dequeueBufferFromNativeWindow() != NULL) {
3094c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        // these buffers will be submitted as regular buffers; account for this
3095c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        if (mStoreMetaDataInOutputBuffers && mMetaDataBuffersToSubmit > 0) {
3096c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar            --mMetaDataBuffersToSubmit;
3097c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        }
30987e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
30997e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
31007e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
3101f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs(
3102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
3103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
3104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
3105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus != BufferInfo::OWNED_BY_US
3107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3108609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGV("[%s] Buffer %u on port %u still has status %d",
3109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mComponentName.c_str(),
3110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info->mBufferID, portIndex, info->mStatus);
3111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
3112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3118f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs() {
3119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return allYourBuffersAreBelongToUs(kPortIndexInput)
3120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        && allYourBuffersAreBelongToUs(kPortIndexOutput);
3121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3123f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::deferMessage(const sp<AMessage> &msg) {
3124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool wasEmptyBefore = mDeferredQueue.empty();
3125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.push_back(msg);
3126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3128f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::processDeferredMessages() {
3129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> > queue = mDeferredQueue;
3130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.clear();
3131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> >::iterator it = queue.begin();
3133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while (it != queue.end()) {
3134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        onMessageReceived(*it++);
3135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
313803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar// static
3139229d242665c612fd97431d1e7ac004823b47f181Lajos Molnarbool ACodec::describeDefaultColorFormat(DescribeColorFormatParams &params) {
314003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    MediaImage &image = params.sMediaImage;
314103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    memset(&image, 0, sizeof(image));
314203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
314303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mType = MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
314403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mNumPlanes = 0;
314503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
314603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    const OMX_COLOR_FORMATTYPE fmt = params.eColorFormat;
314703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mWidth = params.nFrameWidth;
314803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mHeight = params.nFrameHeight;
314903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
315003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    // only supporting YUV420
315103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    if (fmt != OMX_COLOR_FormatYUV420Planar &&
315203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        fmt != OMX_COLOR_FormatYUV420PackedPlanar &&
315303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        fmt != OMX_COLOR_FormatYUV420SemiPlanar &&
315403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        fmt != OMX_COLOR_FormatYUV420PackedSemiPlanar) {
315503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        ALOGW("do not know color format 0x%x = %d", fmt, fmt);
3156229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return false;
315703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    }
315803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
3159b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    // TEMPORARY FIX for some vendors that advertise sliceHeight as 0
3160b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    if (params.nStride != 0 && params.nSliceHeight == 0) {
3161b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        ALOGW("using sliceHeight=%u instead of what codec advertised (=0)",
3162b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar                params.nFrameHeight);
3163b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        params.nSliceHeight = params.nFrameHeight;
3164b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    }
3165b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar
3166b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    // we need stride and slice-height to be non-zero
3167b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    if (params.nStride == 0 || params.nSliceHeight == 0) {
3168b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        ALOGW("cannot describe color format 0x%x = %d with stride=%u and sliceHeight=%u",
3169b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar                fmt, fmt, params.nStride, params.nSliceHeight);
3170b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        return false;
3171b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    }
3172b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar
317303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    // set-up YUV format
317403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mType = MediaImage::MEDIA_IMAGE_TYPE_YUV;
317503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mNumPlanes = 3;
317603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mBitDepth = 8;
317703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mOffset = 0;
317803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mColInc = 1;
317903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mRowInc = params.nStride;
318003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mHorizSubsampling = 1;
318103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mVertSubsampling = 1;
318203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
318303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    switch (fmt) {
318403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420Planar: // used for YV12
318503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420PackedPlanar:
318603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight;
318703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mColInc = 1;
318803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mRowInc = params.nStride / 2;
318903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mHorizSubsampling = 2;
319003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mVertSubsampling = 2;
319103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
319203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset
319303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    + (params.nStride * params.nSliceHeight / 4);
319403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mColInc = 1;
319503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mRowInc = params.nStride / 2;
319603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mHorizSubsampling = 2;
319703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mVertSubsampling = 2;
319803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            break;
319903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
320003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420SemiPlanar:
320103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            // FIXME: NV21 for sw-encoder, NV12 for decoder and hw-encoder
320203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420PackedSemiPlanar:
320303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            // NV12
320403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight;
320503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mColInc = 2;
320603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mRowInc = params.nStride;
320703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mHorizSubsampling = 2;
320803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mVertSubsampling = 2;
320903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
321003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset + 1;
321103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mColInc = 2;
321203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mRowInc = params.nStride;
321303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mHorizSubsampling = 2;
321403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mVertSubsampling = 2;
321503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            break;
321603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
321703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        default:
321803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            TRESPASS();
321903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    }
3220229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    return true;
3221229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar}
3222229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3223229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar// static
3224229d242665c612fd97431d1e7ac004823b47f181Lajos Molnarbool ACodec::describeColorFormat(
3225229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        const sp<IOMX> &omx, IOMX::node_id node,
3226229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        DescribeColorFormatParams &describeParams)
3227229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar{
3228229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    OMX_INDEXTYPE describeColorFormatIndex;
3229229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    if (omx->getExtensionIndex(
3230229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            node, "OMX.google.android.index.describeColorFormat",
3231229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            &describeColorFormatIndex) != OK ||
3232229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        omx->getParameter(
3233229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            node, describeColorFormatIndex,
3234229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            &describeParams, sizeof(describeParams)) != OK) {
3235229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return describeDefaultColorFormat(describeParams);
3236229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    }
3237229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    return describeParams.sMediaImage.mType !=
3238229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
3239229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar}
3240229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3241229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar// static
3242229d242665c612fd97431d1e7ac004823b47f181Lajos Molnarbool ACodec::isFlexibleColorFormat(
3243229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar         const sp<IOMX> &omx, IOMX::node_id node,
3244229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar         uint32_t colorFormat, OMX_U32 *flexibleEquivalent) {
3245229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    DescribeColorFormatParams describeParams;
3246229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    InitOMXParams(&describeParams);
3247229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.eColorFormat = (OMX_COLOR_FORMATTYPE)colorFormat;
3248229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    // reasonable dummy values
3249229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nFrameWidth = 128;
3250229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nFrameHeight = 128;
3251229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nStride = 128;
3252229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nSliceHeight = 128;
3253229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3254229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    CHECK(flexibleEquivalent != NULL);
3255229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3256229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    if (!describeColorFormat(omx, node, describeParams)) {
3257229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return false;
3258229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    }
3259229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3260229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    const MediaImage &img = describeParams.sMediaImage;
3261229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    if (img.mType == MediaImage::MEDIA_IMAGE_TYPE_YUV) {
3262229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        if (img.mNumPlanes != 3 ||
3263229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            img.mPlane[img.Y].mHorizSubsampling != 1 ||
3264229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            img.mPlane[img.Y].mVertSubsampling != 1) {
3265229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            return false;
3266229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
3267229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3268229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        // YUV 420
3269229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        if (img.mPlane[img.U].mHorizSubsampling == 2
3270229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.U].mVertSubsampling == 2
3271229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.V].mHorizSubsampling == 2
3272229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.V].mVertSubsampling == 2) {
3273229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            // possible flexible YUV420 format
3274229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            if (img.mBitDepth <= 8) {
3275229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar               *flexibleEquivalent = OMX_COLOR_FormatYUV420Flexible;
3276229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar               return true;
3277229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            }
3278229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
3279229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    }
3280229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    return false;
328103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar}
328203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
3283e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarstatus_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> &notify) {
3284e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    // TODO: catch errors an return them instead of using CHECK
328531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
328631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    InitOMXParams(&def);
3287e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    def.nPortIndex = portIndex;
328831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
328931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ(mOMX->getParameter(
329031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)),
329131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber             (status_t)OK);
329231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3293e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ((int)def.eDir,
3294e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            (int)(portIndex == kPortIndexOutput ? OMX_DirOutput : OMX_DirInput));
329531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
329631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    switch (def.eDomain) {
329731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainVideo:
329831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
329931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
3300e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            switch ((int)videoDef->eCompressionFormat) {
3301e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_VIDEO_CodingUnused:
3302e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3303e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(mIsEncoder ^ (portIndex == kPortIndexOutput));
3304e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
3305e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3306e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("stride", videoDef->nStride);
3307e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("slice-height", videoDef->nSliceHeight);
3308e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("color-format", videoDef->eColorFormat);
3309e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
331003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    DescribeColorFormatParams describeParams;
331103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    InitOMXParams(&describeParams);
331203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    describeParams.eColorFormat = videoDef->eColorFormat;
331303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    describeParams.nFrameWidth = videoDef->nFrameWidth;
331403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    describeParams.nFrameHeight = videoDef->nFrameHeight;
331503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    describeParams.nStride = videoDef->nStride;
331603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    describeParams.nSliceHeight = videoDef->nSliceHeight;
331703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
3318229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                    if (describeColorFormat(mOMX, mNode, describeParams)) {
331903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                        notify->setBuffer(
332003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                                "image-data",
332103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                                ABuffer::CreateAsCopy(
332203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                                        &describeParams.sMediaImage,
332303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                                        sizeof(describeParams.sMediaImage)));
332403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    }
332503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
332691a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                    if (portIndex != kPortIndexOutput) {
332791a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                        // TODO: also get input crop
332891a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                        break;
332991a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                    }
333091a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar
3331e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_CONFIG_RECTTYPE rect;
3332e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&rect);
333391a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                    rect.nPortIndex = portIndex;
3334e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3335e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    if (mOMX->getConfig(
333691a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                mNode,
333791a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                (portIndex == kPortIndexOutput ?
333891a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                        OMX_IndexConfigCommonOutputCrop :
333991a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                        OMX_IndexConfigCommonInputCrop),
3340e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &rect, sizeof(rect)) != OK) {
3341e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nLeft = 0;
3342e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nTop = 0;
3343e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nWidth = videoDef->nFrameWidth;
3344e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nHeight = videoDef->nFrameHeight;
3345e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    }
334631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3347e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nLeft, 0);
3348e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nTop, 0);
3349e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nWidth, 0u);
3350e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nHeight, 0u);
3351e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_LE(rect.nLeft + rect.nWidth - 1, videoDef->nFrameWidth);
3352e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_LE(rect.nTop + rect.nHeight - 1, videoDef->nFrameHeight);
3353e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3354e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setRect(
3355577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            "crop",
3356577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nLeft,
3357577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nTop,
3358e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                            rect.nLeft + rect.nWidth - 1,
3359e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                            rect.nTop + rect.nHeight - 1);
3360e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3361e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3362e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
33634730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
33644730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP8:
33654730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP9:
33664730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                {
33674730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
33684730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    InitOMXParams(&vp8type);
33694730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    vp8type.nPortIndex = kPortIndexOutput;
33704730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    status_t err = mOMX->getParameter(
33714730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            mNode,
33724730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
33734730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            &vp8type,
33744730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            sizeof(vp8type));
33754730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
33764730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    if (err == OK) {
33774730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        AString tsSchema = "none";
33784730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        if (vp8type.eTemporalPattern
33794730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                == OMX_VIDEO_VPXTemporalLayerPatternWebRTC) {
33804730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            switch (vp8type.nTemporalLayerCount) {
33814730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 1:
33824730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
33834730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.1-layer";
33844730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
33854730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
33864730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 2:
33874730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
33884730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.2-layer";
33894730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
33904730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
33914730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 3:
33924730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
33934730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.3-layer";
33944730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
33954730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
33964730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                default:
33974730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
33984730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
33994730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
34004730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            }
34014730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        }
34024730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        notify->setString("ts-schema", tsSchema);
34034730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    }
34044730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    // Fall through to set up mime.
34054730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                }
34064730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
3407e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                default:
3408e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3409e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(mIsEncoder ^ (portIndex == kPortIndexInput));
3410e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    AString mime;
3411e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    if (GetMimeTypeForVideoCoding(
3412e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        videoDef->eCompressionFormat, &mime) != OK) {
3413e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", "application/octet-stream");
3414e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    } else {
3415e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", mime.c_str());
3416e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    }
3417e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3418e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
341931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            }
3420e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3421e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("width", videoDef->nFrameWidth);
3422e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("height", videoDef->nFrameHeight);
342331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
342431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
342531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
342631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainAudio:
342731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
342831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
342931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
343097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            switch ((int)audioDef->eEncoding) {
3431e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingPCM:
3432e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3433e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_PCMMODETYPE params;
3434e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3435e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3436e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3437e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3438e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioPcm,
3439e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3440e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3441e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
344214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_GT(params.nChannels, 0);
3443e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK(params.nChannels == 1 || params.bInterleaved);
3444e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(params.nBitPerSample, 16u);
344514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
344614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.eNumData,
344714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_NumericalDataSigned);
344814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
344914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.ePCMMode,
345014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_AUDIO_PCMModeLinear);
3451e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3452e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
3453e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
3454e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSamplingRate);
3455e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3456e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mChannelMaskPresent) {
3457e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("channel-mask", mChannelMask);
34588b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                    }
3459e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
34608b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                }
34619806555d3930be43e11106281dee354820ac1c88Andreas Huber
3462e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAAC:
3463e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3464e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AACPROFILETYPE params;
3465e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3466e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3467e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3468e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3469e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAac,
3470e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3471e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3472e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3473e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
3474e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
3475e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
3476e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
3477e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
3478e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3479e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAMR:
3480e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3481e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AMRTYPE params;
3482e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3483e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
34849806555d3930be43e11106281dee354820ac1c88Andreas Huber
3485e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3486e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAmr,
3487e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3488e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3489e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3490e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", 1);
3491e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) {
3492e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
3493e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_WB);
3494e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3495e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 16000);
3496e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    } else {
3497e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
3498e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
3499e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3500e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 8000);
3501e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
3502e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
3503e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
3504e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3505e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingFLAC:
3506e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3507e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_FLACTYPE params;
3508e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3509e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3510e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3511e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3512e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioFlac,
3513e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3514e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3515e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3516e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC);
3517e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
3518e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
3519e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
3520e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
3521e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3522e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingMP3:
3523e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3524e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_MP3TYPE params;
3525e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
3526e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3527e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3528e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_EQ(mOMX->getParameter(
3529e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                mNode, OMX_IndexParamAudioMp3,
3530e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &params, sizeof(params)),
3531e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                             (status_t)OK);
3532e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3533e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MPEG);
3534e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
3535e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
3536e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3537e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
3538e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3539e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingVORBIS:
3540e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3541e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_VORBISTYPE params;
3542e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
3543e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3544e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3545e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_EQ(mOMX->getParameter(
3546e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                mNode, OMX_IndexParamAudioVorbis,
3547e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &params, sizeof(params)),
3548e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                             (status_t)OK);
3549e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3550e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_VORBIS);
3551e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
3552e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
3553e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3554e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
3555e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
355697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                case OMX_AUDIO_CodingAndroidAC3:
355797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                {
355897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    OMX_AUDIO_PARAM_ANDROID_AC3TYPE params;
355997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    InitOMXParams(&params);
3560e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
356197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
356297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    CHECK_EQ((status_t)OK, mOMX->getParameter(
356397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            mNode,
356497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
356597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            &params,
356697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            sizeof(params)));
356797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
356897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AC3);
356997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("channel-count", params.nChannels);
357097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("sample-rate", params.nSampleRate);
357197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    break;
357297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                }
3573e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
35748a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                case OMX_AUDIO_CodingAndroidEAC3:
35758a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                {
35768a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    OMX_AUDIO_PARAM_ANDROID_EAC3TYPE params;
35778a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    InitOMXParams(&params);
35788a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    params.nPortIndex = portIndex;
35798a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
35808a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    CHECK_EQ((status_t)OK, mOMX->getParameter(
35818a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                            mNode,
35828a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
35838a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                            &params,
35848a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                            sizeof(params)));
35858a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
35868a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_EAC3);
35878a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setInt32("channel-count", params.nChannels);
35888a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setInt32("sample-rate", params.nSampleRate);
35898a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    break;
35908a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                }
35918a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
35928c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                case OMX_AUDIO_CodingAndroidOPUS:
35938c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                {
35948c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    OMX_AUDIO_PARAM_ANDROID_OPUSTYPE params;
35958c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    InitOMXParams(&params);
35968c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    params.nPortIndex = portIndex;
35978c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
35988c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    CHECK_EQ((status_t)OK, mOMX->getParameter(
35998c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            mNode,
36008c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus,
36018c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            &params,
36028c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            sizeof(params)));
36038c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
36048c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_OPUS);
36058c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("channel-count", params.nChannels);
36068c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("sample-rate", params.nSampleRate);
36078c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    break;
36088c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                }
36098c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
361010d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                case OMX_AUDIO_CodingG711:
361110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                {
361210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    OMX_AUDIO_PARAM_PCMMODETYPE params;
361310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    InitOMXParams(&params);
361410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    params.nPortIndex = portIndex;
361510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
361610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    CHECK_EQ((status_t)OK, mOMX->getParameter(
361710d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                            mNode,
361810d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                            (OMX_INDEXTYPE)OMX_IndexParamAudioPcm,
361910d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                            &params,
362010d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                            sizeof(params)));
362110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
362210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    const char *mime = NULL;
362310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    if (params.ePCMMode == OMX_AUDIO_PCMModeMULaw) {
362410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_G711_MLAW;
362510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    } else if (params.ePCMMode == OMX_AUDIO_PCMModeALaw) {
362610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_G711_ALAW;
362710d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    } else { // params.ePCMMode == OMX_AUDIO_PCMModeLinear
362810d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_RAW;
362910d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    }
363010d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setString("mime", mime);
363110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setInt32("channel-count", params.nChannels);
363210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setInt32("sample-rate", params.nSamplingRate);
363310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    break;
363410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                }
363510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
3636e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                default:
3637e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    ALOGE("UNKNOWN AUDIO CODING: %d\n", audioDef->eEncoding);
3638e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    TRESPASS();
3639e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
364031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
364131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
364231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
364331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        default:
364431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            TRESPASS();
364531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    }
364631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3647e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    return OK;
3648e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar}
3649e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3650e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarvoid ACodec::sendFormatChange(const sp<AMessage> &reply) {
36514e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    sp<AMessage> notify = mBaseOutputFormat->dup();
3652e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    notify->setInt32("what", kWhatOutputFormatChanged);
3653e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3654e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ(getPortFormat(kPortIndexOutput, notify), (status_t)OK);
3655e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3656e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    AString mime;
3657e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK(notify->findString("mime", &mime));
3658e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3659e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    int32_t left, top, right, bottom;
3660e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if (mime == MEDIA_MIMETYPE_VIDEO_RAW &&
3661e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        mNativeWindow != NULL &&
3662e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->findRect("crop", &left, &top, &right, &bottom)) {
3663e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        // notify renderer of the crop change
3664e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        // NOTE: native window uses extended right-bottom coordinate
3665e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        reply->setRect("crop", left, top, right + 1, bottom + 1);
3666e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    } else if (mime == MEDIA_MIMETYPE_AUDIO_RAW &&
3667e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar               (mEncoderDelay || mEncoderPadding)) {
3668e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        int32_t channelCount;
3669e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        CHECK(notify->findInt32("channel-count", &channelCount));
3670e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        size_t frameSize = channelCount * sizeof(int16_t);
3671e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        if (mSkipCutBuffer != NULL) {
3672e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            size_t prevbufsize = mSkipCutBuffer->size();
3673e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            if (prevbufsize != 0) {
3674e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                ALOGW("Replacing SkipCutBuffer holding %d "
3675e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                      "bytes",
3676e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                      prevbufsize);
3677e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            }
3678e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        }
3679e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        mSkipCutBuffer = new SkipCutBuffer(
3680e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                mEncoderDelay * frameSize,
3681e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                mEncoderPadding * frameSize);
3682e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
3683e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
368431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->post();
368531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
368631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mSentFormat = true;
368731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber}
368831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
36895778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
3690cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    sp<AMessage> notify = mNotify->dup();
3691d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatError);
3692251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    ALOGE("signalError(omxError %#x, internalError %d)", error, internalError);
3693251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
3694251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (internalError == UNKNOWN_ERROR) { // find better error code
3695251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        const status_t omxStatus = statusFromOMXError(error);
3696251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        if (omxStatus != 0) {
3697251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            internalError = omxStatus;
3698251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        } else {
3699251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            ALOGW("Invalid OMX error %#x", error);
3700251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        }
3701251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
37025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("err", internalError);
3703251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    notify->setInt32("actionCode", ACTION_CODE_FATAL); // could translate from OMX error.
3704cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->post();
3705cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber}
3706cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber
3707bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huberstatus_t ACodec::pushBlankBuffersToNativeWindow() {
3708bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    status_t err = NO_ERROR;
3709bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    ANativeWindowBuffer* anb = NULL;
3710bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int numBufs = 0;
3711bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int minUndequeuedBufs = 0;
3712bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3713bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We need to reconnect to the ANativeWindow as a CPU client to ensure that
3714bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // no frames get dropped by SurfaceFlinger assuming that these are video
3715bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // frames.
3716bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_disconnect(mNativeWindow.get(),
3717bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_MEDIA);
3718bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3719bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
3720bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3721bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
3722bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3723bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3724bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_connect(mNativeWindow.get(),
3725bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_CPU);
3726bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3727bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
3728bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3729bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
3730bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3731bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3732bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffers_geometry(mNativeWindow.get(), 1, 1,
3733bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            HAL_PIXEL_FORMAT_RGBX_8888);
3734bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3735bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffers_geometry failed: %s (%d)",
3736bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3737bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
3738bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3739bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
374087eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin    err = native_window_set_scaling_mode(mNativeWindow.get(),
374187eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
374287eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin    if (err != NO_ERROR) {
374387eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin        ALOGE("error pushing blank_frames: set_scaling_mode failed: %s (%d)",
374487eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin              strerror(-err), -err);
374587eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin        goto error;
3746bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3747bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3748bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_usage(mNativeWindow.get(),
3749bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            GRALLOC_USAGE_SW_WRITE_OFTEN);
3750bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3751bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_usage failed: %s (%d)",
3752bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3753bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
3754bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3755bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3756bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = mNativeWindow->query(mNativeWindow.get(),
3757bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs);
3758bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3759bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: MIN_UNDEQUEUED_BUFFERS query "
3760bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                "failed: %s (%d)", strerror(-err), -err);
3761bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
3762bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3763bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3764bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    numBufs = minUndequeuedBufs + 1;
3765bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffer_count(mNativeWindow.get(), numBufs);
3766bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3767bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffer_count failed: %s (%d)",
3768bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3769bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
3770bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3771bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3772bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We  push numBufs + 1 buffers to ensure that we've drawn into the same
3773bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // buffer twice.  This should guarantee that the buffer has been displayed
3774bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // on the screen and then been replaced, so an previous video frames are
3775bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // guaranteed NOT to be currently displayed.
3776bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    for (int i = 0; i < numBufs + 1; i++) {
37771e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        int fenceFd = -1;
37781e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &anb);
3779bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3780bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: dequeueBuffer failed: %s (%d)",
3781bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3782bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
3783bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3784bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3785bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
3786bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3787bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Fill the buffer with the a 1x1 checkerboard pattern ;)
3788bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        uint32_t* img = NULL;
3789bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
3790bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3791bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: lock failed: %s (%d)",
3792bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3793bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
3794bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3795bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3796bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        *img = 0;
3797bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3798bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->unlock();
3799bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3800bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: unlock failed: %s (%d)",
3801bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3802bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
3803bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3804bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3805bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->queueBuffer(mNativeWindow.get(),
38061e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                buf->getNativeBuffer(), -1);
3807bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3808bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: queueBuffer failed: %s (%d)",
3809bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3810bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
3811bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3812bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3813bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        anb = NULL;
3814bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3815bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3816bc098410be55f9d96f394b3981a0c482b83859b6Andreas Hubererror:
3817bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3818bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3819bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after an error.
3820bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (anb != NULL) {
38211e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis            mNativeWindow->cancelBuffer(mNativeWindow.get(), anb, -1);
3822bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3823bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3824bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_disconnect(mNativeWindow.get(),
3825bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
3826bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_connect(mNativeWindow.get(),
3827bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
3828bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3829bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
3830bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    } else {
3831bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after success.
3832bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_disconnect(mNativeWindow.get(),
3833bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
3834bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3835bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
3836bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3837bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
3838bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3839bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3840bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_connect(mNativeWindow.get(),
3841bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
3842bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3843bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
3844bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3845bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
3846bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3847bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3848bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return NO_ERROR;
3849bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3850bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber}
3851bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3854eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberACodec::PortDescription::PortDescription() {
3855eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3856eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3857496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t ACodec::requestIDRFrame() {
3858496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    if (!mIsEncoder) {
3859496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        return ERROR_UNSUPPORTED;
3860496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    }
3861496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
3862496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    OMX_CONFIG_INTRAREFRESHVOPTYPE params;
3863496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    InitOMXParams(&params);
3864496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
3865496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.nPortIndex = kPortIndexOutput;
3866496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.IntraRefreshVOP = OMX_TRUE;
3867496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
3868496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    return mOMX->setConfig(
3869496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            mNode,
3870496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            OMX_IndexConfigVideoIntraVOPRefresh,
3871496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            &params,
3872496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            sizeof(params));
3873496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
3874496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
3875eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubervoid ACodec::PortDescription::addBuffer(
3876eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        IOMX::buffer_id id, const sp<ABuffer> &buffer) {
3877eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBufferIDs.push_back(id);
3878eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBuffers.push_back(buffer);
3879eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3880eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3881eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersize_t ACodec::PortDescription::countBuffers() {
3882eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.size();
3883eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3884eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3885eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberIOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const {
3886eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.itemAt(index);
3887eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3888eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3889eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const {
3890eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBuffers.itemAt(index);
3891eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3892eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3893eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber////////////////////////////////////////////////////////////////////////////////
3894eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3895f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
3896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : AState(parentState),
3897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mCodec(codec) {
3898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3900ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas HuberACodec::BaseState::PortMode ACodec::BaseState::getPortMode(
3901ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
3902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return KEEP_BUFFERS;
3903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3905f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
3906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatInputBufferFilled:
3908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onInputBufferFilled(msg);
3910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatOutputBufferDrained:
3914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onOutputBufferDrained(msg);
3916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatOMXMessage:
3920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXMessage(msg);
3922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
39247cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
39257cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
39267cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
3927251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            // This may result in an app illegal state exception.
39287cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            ALOGE("Message 0x%x was not handled", msg->what());
39297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
39307cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            return true;
39317cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
39327cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
3933ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        case ACodec::kWhatOMXDied:
3934ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        {
3935251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            // This will result in kFlagSawMediaServerDie handling in MediaCodec.
3936ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            ALOGE("OMX/mediaserver died, signalling error!");
3937ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT);
3938ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            break;
3939ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        }
3940ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
394130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        case ACodec::kWhatReleaseCodecInstance:
394230358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        {
394330358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            ALOGI("[%s] forcing the release of codec",
394430358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar                    mCodec->mComponentName.c_str());
394530358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            status_t err = mCodec->mOMX->freeNode(mCodec->mNode);
394630358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            ALOGE_IF("[%s] failed to release codec instance: err=%d",
394730358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar                       mCodec->mComponentName.c_str(), err);
394830358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            sp<AMessage> notify = mCodec->mNotify->dup();
394930358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
395030358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            notify->post();
395130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            break;
395230358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        }
395330358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar
3954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
3956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3961f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
3962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t type;
3963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findInt32("type", &type));
3964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
39655e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // there is a possibility that this is an outstanding message for a
39665e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // codec that we have already destroyed
39675e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    if (mCodec->mNode == NULL) {
39685e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar        ALOGI("ignoring message as already freed component: %s",
39695e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar                msg->debugString().c_str());
39705e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar        return true;
39715e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    }
39725e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar
3973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::node_id nodeID;
3974609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("node", (int32_t*)&nodeID));
3975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(nodeID, mCodec->mNode);
3976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (type) {
3978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EVENT:
3979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t event, data1, data2;
3981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("event", &event));
3982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data1", &data1));
3983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data2", &data2));
3984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
39850af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            if (event == OMX_EventCmdComplete
39860af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data1 == OMX_CommandFlush
39870af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data2 == (int32_t)OMX_ALL) {
39880af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // Use of this notification is not consistent across
39890af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // implementations. We'll drop this notification and rely
39900af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // on flush-complete notifications on the individual port
39910af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // indices instead.
39920af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
39930af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                return true;
39940af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            }
39950af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
3996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEvent(
3997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_EVENTTYPE>(event),
3998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data1),
3999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data2));
4000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EMPTY_BUFFER_DONE:
4003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
4005609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
4006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEmptyBufferDone(bufferID);
4008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::FILL_BUFFER_DONE:
4011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
4013609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
4014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t rangeOffset, rangeLength, flags;
4016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs;
4017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_offset", &rangeOffset));
4019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_length", &rangeLength));
4020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("flags", &flags));
4021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt64("timestamp", &timeUs));
4022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXFillBufferDone(
4024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    bufferID,
4025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (size_t)rangeOffset, (size_t)rangeLength,
4026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (OMX_U32)flags,
4027784e24e386b088c05d653ab482f2e95cb53e3d01Andy Hung                    timeUs);
4028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
4032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4036f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEvent(
4037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (event != OMX_EventError) {
40393856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] EVENT(%d, 0x%08lx, 0x%08lx)",
4040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mCodec->mComponentName.c_str(), event, data1, data2);
4041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return false;
4043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
404529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block    ALOGE("[%s] ERROR(0x%08lx)", mCodec->mComponentName.c_str(), data1);
4046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4047251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // verify OMX component sends back an error we expect.
4048251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    OMX_ERRORTYPE omxError = (OMX_ERRORTYPE)data1;
4049251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (!isOMXError(omxError)) {
4050251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        ALOGW("Invalid OMX error %#x", omxError);
4051251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        omxError = OMX_ErrorUndefined;
4052251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
4053251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    mCodec->signalError(omxError);
4054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4058f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID) {
40593856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] onOMXEmptyBufferDone %p",
4060349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber         mCodec->mComponentName.c_str(), bufferID);
4061349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
4063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexInput, bufferID);
4064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
4066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
4067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
406896e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // We're in "store-metadata-in-buffers" mode, the underlying
406996e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // OMX component had access to data that's implicitly refcounted
407096e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // by this "MediaBuffer" object. Now that the OMX component has
407196e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // told us that it's done with the input buffer, we can decrement
407296e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // the mediaBuffer's reference count.
407396e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    info->mData->setMediaBufferBase(NULL);
4074d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
4076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4081f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            postFillThisBuffer(info);
4083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4086f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
4088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();  // Not currently used
4089f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4094f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4095f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4096f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
4097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
4098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
4099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
4102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
4104d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatFillThisBuffer);
4105609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    notify->setInt32("buffer-id", info->mBufferID);
4106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mData->meta()->clear();
41082d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    notify->setBuffer("buffer", info->mData);
4109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec->id());
4111609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    reply->setInt32("buffer-id", info->mBufferID);
4112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setMessage("reply", reply);
4114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->post();
4116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
4118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4120f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
4121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
4122609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
41232d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    sp<ABuffer> buffer;
4124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t err = OK;
41255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool eos = false;
4126a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar    PortMode mode = getPortMode(kPortIndexInput);
41275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41282d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    if (!msg->findBuffer("buffer", &buffer)) {
4129a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar        /* these are unfilled buffers returned by client */
4130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findInt32("err", &err));
4131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
41327fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        if (err == OK) {
41337fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            /* buffers with no errors are returned on MediaCodec.flush */
41347fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            mode = KEEP_BUFFERS;
41357fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        } else {
41367fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            ALOGV("[%s] saw error %d instead of an input buffer",
41377fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                 mCodec->mComponentName.c_str(), err);
41387fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            eos = true;
41397fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        }
41403831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
41412d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber        buffer.clear();
4142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
41445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
41455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
41465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
41475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = ERROR_END_OF_STREAM;
41485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
41495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
4151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_UPSTREAM);
4152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
4154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
41585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (eos) {
4159dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (!mCodec->mPortEOS[kPortIndexInput]) {
4160dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
4161dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mInputEOSResult = err;
4162dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
4163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
41695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
4170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int64_t timeUs;
4171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
4172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
4174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t isCSD;
4176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
4177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
4178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
4179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
41805778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (eos) {
41815778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    flags |= OMX_BUFFERFLAG_EOS;
41825778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
41835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer != info->mData) {
4185d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGV("[%s] Needs to copy input data for buffer %p. (%p != %p)",
4186d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(),
4187d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         bufferID,
4188d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         buffer.get(), info->mData.get());
4189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    CHECK_LE(buffer->size(), info->mData->capacity());
4191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    memcpy(info->mData->data(), buffer->data(), buffer->size());
4192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
4193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4194078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
41953856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ codec specific data",
4196078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID);
41975778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else if (flags & OMX_BUFFERFLAG_EOS) {
41985778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] calling emptyBuffer %p w/ EOS",
41995778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str(), bufferID);
4200078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                } else {
4201d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
4202d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGI("[%s] calling emptyBuffer %p w/ time %lld us",
4203d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
4204d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#else
42053856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ time %lld us",
4206078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
4207d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
4208078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                }
4209349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4210d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
4211d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ACodec::BufferStats stats;
4212d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
4213d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mFillBufferDoneTimeUs = -1ll;
4214d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mCodec->mBufferStats.add(timeUs, stats);
4215d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
4216d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4217054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                if (mCodec->mStoreMetaDataInOutputBuffers) {
4218054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    // try to submit an output buffer for each input buffer
4219054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    PortMode outputMode = getPortMode(kPortIndexOutput);
4220054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4221054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    ALOGV("MetaDataBuffersToSubmit=%u portMode=%s",
4222054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            mCodec->mMetaDataBuffersToSubmit,
4223054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            (outputMode == FREE_BUFFERS ? "FREE" :
4224054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                             outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
4225054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    if (outputMode == RESUBMIT_BUFFERS) {
4226e53350373ac516257b4f8956ff1e3f1ac48f607eLajos Molnar                        mCodec->submitOutputMetaDataBuffer();
4227054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    }
4228054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                }
4229054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
4231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
4232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
4233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
4234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            buffer->size(),
4235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            flags,
4236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            timeUs),
4237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
42415778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (!eos) {
42425778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    getMoreInputDataIfPossible();
42435778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
42445778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] Signalled EOS on the input port",
42455778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str());
42465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
42475778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
42485778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mInputEOSResult = err;
42495778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
4250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
4251dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (err != ERROR_END_OF_STREAM) {
42523856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port "
4253dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         "due to error %d",
4254dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str(), err);
4255dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                } else {
42563856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port",
4257dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str());
4258dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
4259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
42603856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] calling emptyBuffer %p signalling EOS",
4261349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                     mCodec->mComponentName.c_str(), bufferID);
4262349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
4264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
4265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
4266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
4267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
4268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_BUFFERFLAG_EOS,
4269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0),
4270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexInput] = true;
4275dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                mCodec->mInputEOSResult = err;
4276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4279625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih
4280625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih        default:
4281625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
4282625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih            break;
4283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4286f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::getMoreInputDataIfPossible() {
4287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
4288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
4289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *eligible = NULL;
4292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
4294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
4295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
4297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
4298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // There's already a "read" pending.
4299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
4300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
4302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_US) {
4304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            eligible = info;
4305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (eligible == NULL) {
4309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
4310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(eligible);
4313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4315f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXFillBufferDone(
4316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferID,
4317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        size_t rangeOffset, size_t rangeLength,
4318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 flags,
4319784e24e386b088c05d653ab482f2e95cb53e3d01Andy Hung        int64_t timeUs) {
4320609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] onOMXFillBufferDone %u time %" PRId64 " us, flags = 0x%08x",
43215778822d86b0337407514b9372562b86edfa91cdAndreas Huber         mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
4322349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
4324d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4325d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
4326d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    index = mCodec->mBufferStats.indexOfKey(timeUs);
4327d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (index >= 0) {
4328d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
4329d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
4330d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4331d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ALOGI("frame PTS %lld: %lld",
4332d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                timeUs,
4333d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
4334d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4335d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mCodec->mBufferStats.removeItemsAt(index);
4336d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats = NULL;
4337d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
4338d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
4339d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
4341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
4342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
4344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4345054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mDequeuedAt = ++mCodec->mDequeueCounter;
4346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
4347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
4349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4356a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            if (rangeLength == 0 && (!(flags & OMX_BUFFERFLAG_EOS)
4357a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                    || mCodec->mPortEOS[kPortIndexOutput])) {
4358609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                ALOGV("[%s] calling fillBuffer %u",
43595778822d86b0337407514b9372562b86edfa91cdAndreas Huber                     mCodec->mComponentName.c_str(), info->mBufferID);
4360349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
43615778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK_EQ(mCodec->mOMX->fillBuffer(
43625778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mCodec->mNode, info->mBufferID),
43635778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         (status_t)OK);
4364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
43655778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
43665778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
43675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
436831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4369577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            sp<AMessage> reply =
4370577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                new AMessage(kWhatOutputBufferDrained, mCodec->id());
4371577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
43724bdda35319d5f46efea2089b865c8a64816389cdMarco Nelissen            if (!mCodec->mSentFormat && rangeLength > 0) {
4373577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->sendFormatChange(reply);
43745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
4375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4376308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            if (mCodec->mUseMetadataOnEncoderOutput) {
4377308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                native_handle_t* handle =
4378308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        *(native_handle_t**)(info->mData->data() + 4);
4379308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setPointer("handle", handle);
4380308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeOffset", rangeOffset);
4381308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeLength", rangeLength);
4382308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            } else {
4383308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->setRange(rangeOffset, rangeLength);
4384308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            }
4385496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#if 0
438621ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen            if (mCodec->mNativeWindow == NULL) {
4387496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                if (IsIDR(info->mData)) {
4388496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                    ALOGI("IDR frame");
4389496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                }
43905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
439121ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen#endif
4392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
43938b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            if (mCodec->mSkipCutBuffer != NULL) {
43948b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                mCodec->mSkipCutBuffer->submit(info->mData);
43958b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            }
43965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mData->meta()->setInt64("timeUs", timeUs);
4397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
43985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4399d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatDrainThisBuffer);
4400609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            notify->setInt32("buffer-id", info->mBufferID);
44012d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            notify->setBuffer("buffer", info->mData);
44025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("flags", flags);
4403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4404609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            reply->setInt32("buffer-id", info->mBufferID);
4405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
44065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setMessage("reply", reply);
4407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
44085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->post();
44095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
44105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
4411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (flags & OMX_BUFFERFLAG_EOS) {
44135778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
44145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                sp<AMessage> notify = mCodec->mNotify->dup();
4416d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar                notify->setInt32("what", CodecBase::kWhatEOS);
4417dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                notify->setInt32("err", mCodec->mInputEOSResult);
4418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->post();
4419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexOutput] = true;
4421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
4428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
4430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
4431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4438f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
4439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
4440609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
4441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
4442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
4443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
4444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM);
4445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4446577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    android_native_rect_t crop;
4447577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    if (msg->findRect("crop",
4448577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            &crop.left, &crop.top, &crop.right, &crop.bottom)) {
4449577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar        CHECK_EQ(0, native_window_set_crop(
4450577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->mNativeWindow.get(), &crop));
4451577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    }
4452577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
4453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t render;
4454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mNativeWindow != NULL
44556aade6058521b0dbd35a9a4620f4d04f02f90444Marco Nelissen            && msg->findInt32("render", &render) && render != 0
445679ee2399b67c7a11042c5904dc1309712a76f8cbJianzheng Zhou            && info->mData != NULL && info->mData->size() != 0) {
44576fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        ATRACE_NAME("render");
4458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The client wants this buffer to be rendered.
4459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4460fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        int64_t timestampNs = 0;
4461fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        if (!msg->findInt64("timestampNs", &timestampNs)) {
4462fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // TODO: it seems like we should use the timestamp
4463fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // in the (media)buffer as it potentially came from
4464fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // an input surface, but we did not propagate it prior to
4465fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // API 20.  Perhaps check for target SDK version.
4466fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#if 0
4467fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            if (info->mData->meta()->findInt64("timeUs", &timestampNs)) {
446847aea1f7c58f5302b16822f9e7e1763f2af04ef5Lajos Molnar                ALOGV("using buffer PTS of %" PRId64, timestampNs);
4469fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar                timestampNs *= 1000;
4470fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            }
4471fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#endif
4472fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
4473fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
44745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err;
4475fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        err = native_window_set_buffers_timestamp(mCodec->mNativeWindow.get(), timestampNs);
4476fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        if (err != OK) {
4477fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            ALOGW("failed to set buffer timestamp: %d", err);
4478fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
4479fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
44805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if ((err = mCodec->mNativeWindow->queueBuffer(
4481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNativeWindow.get(),
44821e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                    info->mGraphicBuffer.get(), -1)) == OK) {
4483cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
4484cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        } else {
4485251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
4486cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
4487cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        }
4488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
44896fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        if (mCodec->mNativeWindow != NULL &&
44906fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar            (info->mData == NULL || info->mData->size() != 0)) {
44916fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar            ATRACE_NAME("frame-drop");
44926fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        }
4493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_US;
4494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
4497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
4502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // We cannot resubmit the buffer we just rendered, dequeue
4505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // the spare instead.
4506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info = mCodec->dequeueBufferFromNativeWindow();
4508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (!mCodec->mPortEOS[kPortIndexOutput]) {
4515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // We cannot resubmit the buffer we just rendered, dequeue
4517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // the spare instead.
4518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info = mCodec->dequeueBufferFromNativeWindow();
4520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
4521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4522c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                if (info != NULL) {
4523609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                    ALOGV("[%s] calling fillBuffer %u",
4524c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                         mCodec->mComponentName.c_str(), info->mBufferID);
4525349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4526c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
4527c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                             (status_t)OK);
4528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4529c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4530c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                }
4531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
4538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
4540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
4541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4548f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::UninitializedState::UninitializedState(ACodec *codec)
4549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4552c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::UninitializedState::stateEntered() {
4553c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("Now uninitialized");
4554ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4555ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (mDeathNotifier != NULL) {
4556ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mCodec->mOMX->asBinder()->unlinkToDeath(mDeathNotifier);
4557ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
4558ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
4559ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4560ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNativeWindow.clear();
4561ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNode = NULL;
4562ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mOMX.clear();
4563ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mQuirks = 0;
4564ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mFlags = 0;
4565308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    mCodec->mUseMetadataOnEncoderOutput = 0;
4566ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mComponentName.clear();
4567c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4568c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4569f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
4570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatSetup:
4574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onSetup(msg);
4576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
45815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case ACodec::kWhatAllocateComponent:
45825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
45835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            onAllocateComponent(msg);
45845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            handled = true;
45855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
45865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
45875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatShutdown:
4589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4590c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
4591c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
4592c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
459354b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            ALOGW_IF(keepComponentAllocated,
459454b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar                     "cannot keep component allocated on shutdown in Uninitialized state");
4595c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4597d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
4598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
4599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4601c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
4602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatFlush:
4605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4607d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
4608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
4609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4611c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
4612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
461430358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        case ACodec::kWhatReleaseCodecInstance:
461530358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        {
461630358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            // nothing to do, as we have already signaled shutdown
461730358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            handled = true;
461830358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            break;
461930358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        }
462030358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar
4621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
4623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4628f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::UninitializedState::onSetup(
4629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4630c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (onAllocateComponent(msg)
4631c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            && mCodec->mLoadedState->onConfigureComponent(msg)) {
4632c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mLoadedState->onStart();
4633c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
46345778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
46355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4636c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
46375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onAllocateComponent");
46385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4639c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    CHECK(mCodec->mNode == NULL);
46405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMXClient client;
4642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(client.connect(), (status_t)OK);
4643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<IOMX> omx = client.interface();
4645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4646ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec->id());
4647ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4648ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mDeathNotifier = new DeathNotifier(notify);
4649ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (omx->asBinder()->linkToDeath(mDeathNotifier) != OK) {
4650ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // This was a local binder, if it dies so do we, we won't care
4651ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // about any notifications in the afterlife.
4652ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
4653ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
4654ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4655e671207115fac3914134c61b336d5fa0242c68caAndreas Huber    Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs;
46565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    AString mime;
4658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
46595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString componentName;
4660d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint32_t quirks = 0;
46617791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen    int32_t encoder = false;
46625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findString("componentName", &componentName)) {
4663e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        ssize_t index = matchingCodecs.add();
4664e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        OMXCodec::CodecNameAndQuirks *entry = &matchingCodecs.editItemAt(index);
4665e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        entry->mName = String8(componentName.c_str());
4666afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
4667e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        if (!OMXCodec::findCodecQuirks(
4668e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                    componentName.c_str(), &entry->mQuirks)) {
4669e671207115fac3914134c61b336d5fa0242c68caAndreas Huber            entry->mQuirks = 0;
4670afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
46715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
46725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(msg->findString("mime", &mime));
46735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
46745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("encoder", &encoder)) {
46755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder = false;
46765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
46775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
46785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMXCodec::findMatchingCodecs(
46795778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mime.c_str(),
46805778822d86b0337407514b9372562b86edfa91cdAndreas Huber                encoder, // createEncoder
46815778822d86b0337407514b9372562b86edfa91cdAndreas Huber                NULL,  // matchComponentName
46825778822d86b0337407514b9372562b86edfa91cdAndreas Huber                0,     // flags
4683e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                &matchingCodecs);
46845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
46851065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
46861065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    sp<CodecObserver> observer = new CodecObserver;
46871065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    IOMX::node_id node = NULL;
46881065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
46891065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
46901065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            ++matchIndex) {
4691e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        componentName = matchingCodecs.itemAt(matchIndex).mName.string();
4692e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        quirks = matchingCodecs.itemAt(matchIndex).mQuirks;
4693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4694078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        pid_t tid = androidGetTid();
4695078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        int prevPriority = androidGetThreadPriority(tid);
4696078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
46971065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        status_t err = omx->allocateNode(componentName.c_str(), observer, &node);
4698078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, prevPriority);
4699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
47001065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        if (err == OK) {
47011065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            break;
47027a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He        } else {
47037a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He            ALOGW("Allocating component '%s' failed, try next one.", componentName.c_str());
47041065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
47051065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
47061065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        node = NULL;
47071065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    }
47081065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
4709c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    if (node == NULL) {
47105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!mime.empty()) {
47117791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen            ALOGE("Unable to instantiate a %scoder for type '%s'.",
47127791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen                    encoder ? "en" : "de", mime.c_str());
47135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
47147791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen            ALOGE("Unable to instantiate codec '%s'.", componentName.c_str());
47155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
4716c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
4717cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        mCodec->signalError(OMX_ErrorComponentNotFound);
4718c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
4719c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
4720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4721ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    notify = new AMessage(kWhatOMXMessage, mCodec->id());
4722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    observer->setNotificationMessage(notify);
4723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mComponentName = componentName;
4725ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    mCodec->mFlags = 0;
4726ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
4727ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (componentName.endsWith(".secure")) {
4728ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        mCodec->mFlags |= kFlagIsSecure;
47291713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        mCodec->mFlags |= kFlagIsGrallocUsageProtected;
47300167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
4731ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
4732ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
4733afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mCodec->mQuirks = quirks;
4734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mOMX = omx;
4735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mNode = node;
4736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
47375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
47385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
4739d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatComponentAllocated);
47405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setString("componentName", mCodec->mComponentName.c_str());
47415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
47425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4743c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4744c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mCodec->changeState(mCodec->mLoadedState);
4745c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4746c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
47475778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
47485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4749c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
4750c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4751c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas HuberACodec::LoadedState::LoadedState(ACodec *codec)
4752c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    : BaseState(codec) {
4753c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4754c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4755c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::stateEntered() {
4756c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
4757c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4758f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mPortEOS[kPortIndexInput] =
4759f6f38287b97ec69b169387add6458f859b770e65Andreas Huber        mCodec->mPortEOS[kPortIndexOutput] = false;
4760f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
4761f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mInputEOSResult = OK;
4762f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
4763054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mDequeueCounter = 0;
4764054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mMetaDataBuffersToSubmit = 0;
4765a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    mCodec->mRepeatFrameDelayUs = -1ll;
4766e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mInputFormat.clear();
4767e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mOutputFormat.clear();
47684e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    mCodec->mBaseOutputFormat.clear();
4769054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4770c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (mCodec->mShutdownInProgress) {
4771c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
4772c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4773c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mShutdownInProgress = false;
4774c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mKeepComponentAllocated = false;
4775c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4776c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        onShutdown(keepComponentAllocated);
4777c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
477854b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    mCodec->mExplicitShutdown = false;
4779f393c33e65ae51a7cf168b4e15771b152f996b32Wei Jia
4780f393c33e65ae51a7cf168b4e15771b152f996b32Wei Jia    mCodec->processDeferredMessages();
4781c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4782c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4783c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
4784c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (!keepComponentAllocated) {
4785c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK);
4786c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4787c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->changeState(mCodec->mUninitializedState);
4788c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
4789c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
479054b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    if (mCodec->mExplicitShutdown) {
479154b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        sp<AMessage> notify = mCodec->mNotify->dup();
4792d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
479354b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        notify->post();
479454b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        mCodec->mExplicitShutdown = false;
479554b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    }
4796c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4797c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4798c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
4799c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool handled = false;
4800c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4801c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    switch (msg->what()) {
4802c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatConfigureComponent:
4803c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
4804c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onConfigureComponent(msg);
4805c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
4806c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
4807c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
4808c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
48097cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
48107cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
48117cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            onCreateInputSurface(msg);
48127cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
48137cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
48147cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
48157cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4816c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatStart:
4817c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
4818c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onStart();
4819c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
4820c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
4821c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
4822c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4823c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatShutdown:
4824c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
4825c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
4826c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
4827c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
4828c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
482954b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
4830c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onShutdown(keepComponentAllocated);
4831c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4832c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
4833c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
4834c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
4835c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4836c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatFlush:
4837c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
4838c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4839d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
4840c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->post();
4841c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4842c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
4843c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
4844c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
4845c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4846c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        default:
4847c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            return BaseState::onMessageReceived(msg);
4848c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
4849c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4850c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return handled;
4851c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4852c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4853c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onConfigureComponent(
48545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg) {
48555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onConfigureComponent");
48565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
48575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(mCodec->mNode != NULL);
48585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
48595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString mime;
48605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findString("mime", &mime));
48615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
48625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mCodec->configureCodec(mime.c_str(), msg);
48635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
48645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
4865c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        ALOGE("[%s] configureCodec returning error %d",
4866c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber              mCodec->mComponentName.c_str(), err);
4867c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber
4868251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
4869c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
48705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<RefBase> obj;
4873386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    if (msg->findObject("native-window", &obj)
48745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            && strncmp("OMX.google.", mCodec->mComponentName.c_str(), 11)) {
48751173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        sp<NativeWindowWrapper> nativeWindow(
48761173118eace0e9e347cb007f0da817cee87579edGlenn Kasten                static_cast<NativeWindowWrapper *>(obj.get()));
48771173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        CHECK(nativeWindow != NULL);
48781173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        mCodec->mNativeWindow = nativeWindow->getNativeWindow();
48791ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber
48801ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber        native_window_set_scaling_mode(
48811ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                mCodec->mNativeWindow.get(),
48821ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
4883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((status_t)OK, mCodec->initNativeWindow());
4885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
48865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
48875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
4888d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatComponentConfigured);
4889e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("input-format", mCodec->mInputFormat);
4890e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("output-format", mCodec->mOutputFormat);
48915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
48925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4893c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4894c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
48955778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
48965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
48977cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::LoadedState::onCreateInputSurface(
4898ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        const sp<AMessage> & /* msg */) {
48997cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    ALOGV("onCreateInputSurface");
49007cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
49017cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<AMessage> notify = mCodec->mNotify->dup();
4902d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatInputSurfaceCreated);
49037cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
49047cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<IGraphicBufferProducer> bufferProducer;
49057cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    status_t err;
49067cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
49077cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    err = mCodec->mOMX->createInputSurface(mCodec->mNode, kPortIndexInput,
49087cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            &bufferProducer);
4909a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
4910a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    if (err == OK && mCodec->mRepeatFrameDelayUs > 0ll) {
4911a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        err = mCodec->mOMX->setInternalOption(
4912a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                mCodec->mNode,
4913a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                kPortIndexInput,
4914a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY,
4915a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                &mCodec->mRepeatFrameDelayUs,
4916a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                sizeof(mCodec->mRepeatFrameDelayUs));
4917a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
4918a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (err != OK) {
4919a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            ALOGE("[%s] Unable to configure option to repeat previous "
4920a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  "frames (err %d)",
4921a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  mCodec->mComponentName.c_str(),
4922a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  err);
4923a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
4924a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
4925a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
49262c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    if (err == OK && mCodec->mMaxPtsGapUs > 0ll) {
492794ee4b708acfa941581160b267afb79192b1d816Chong Zhang        err = mCodec->mOMX->setInternalOption(
492894ee4b708acfa941581160b267afb79192b1d816Chong Zhang                mCodec->mNode,
492994ee4b708acfa941581160b267afb79192b1d816Chong Zhang                kPortIndexInput,
493094ee4b708acfa941581160b267afb79192b1d816Chong Zhang                IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP,
493194ee4b708acfa941581160b267afb79192b1d816Chong Zhang                &mCodec->mMaxPtsGapUs,
493294ee4b708acfa941581160b267afb79192b1d816Chong Zhang                sizeof(mCodec->mMaxPtsGapUs));
493394ee4b708acfa941581160b267afb79192b1d816Chong Zhang
493494ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (err != OK) {
493594ee4b708acfa941581160b267afb79192b1d816Chong Zhang            ALOGE("[%s] Unable to configure max timestamp gap (err %d)",
493672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    mCodec->mComponentName.c_str(),
493772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    err);
49382c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
49392c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
49402c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
49412c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    if (err == OK && mCodec->mTimePerCaptureUs > 0ll
49422c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            && mCodec->mTimePerFrameUs > 0ll) {
49432c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        int64_t timeLapse[2];
49442c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[0] = mCodec->mTimePerFrameUs;
49452c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[1] = mCodec->mTimePerCaptureUs;
49462c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        err = mCodec->mOMX->setInternalOption(
49472c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                mCodec->mNode,
49482c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                kPortIndexInput,
49492c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                IOMX::INTERNAL_OPTION_TIME_LAPSE,
49502c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                &timeLapse[0],
49512c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                sizeof(timeLapse));
49522c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
49532c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (err != OK) {
49542c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            ALOGE("[%s] Unable to configure time lapse (err %d)",
49552c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    mCodec->mComponentName.c_str(),
49562c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    err);
49572c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
49582c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
495972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
496072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (err == OK && mCodec->mCreateInputBuffersSuspended) {
496172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        bool suspend = true;
496272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        err = mCodec->mOMX->setInternalOption(
496372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                mCodec->mNode,
496472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                kPortIndexInput,
496572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                IOMX::INTERNAL_OPTION_SUSPEND,
496672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                &suspend,
496772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                sizeof(suspend));
496872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
496972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
497072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("[%s] Unable to configure option to suspend (err %d)",
497194ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  mCodec->mComponentName.c_str(),
497294ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  err);
497394ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
497494ee4b708acfa941581160b267afb79192b1d816Chong Zhang    }
497594ee4b708acfa941581160b267afb79192b1d816Chong Zhang
49767cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err == OK) {
49777cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setObject("input-surface",
49787cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                new BufferProducerWrapper(bufferProducer));
49797cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else {
49807cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // Can't use mCodec->signalError() here -- MediaCodec won't forward
49817cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // the error through because it's in the "configured" state.  We
49827cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // send a kWhatInputSurfaceCreated with an error value instead.
49837cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGE("[%s] onCreateInputSurface returning error %d",
49847cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                mCodec->mComponentName.c_str(), err);
49857cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setInt32("err", err);
49867cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
49877cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->post();
49887cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
49897cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4990c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onStart() {
49915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onStart");
49925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
49935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ(mCodec->mOMX->sendCommand(
49945778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
4995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
4996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->changeState(mCodec->mLoadedToIdleState);
4998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5002f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
5003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5006f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::LoadedToIdleState::stateEntered() {
50073856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
5008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5009cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    status_t err;
5010cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    if ((err = allocateBuffers()) != OK) {
501129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to allocate buffers after transitioning to IDLE state "
5012cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             "(error 0x%08x)",
5013cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             err);
5014cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
5015251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
501691bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber
501791bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber        mCodec->changeState(mCodec->mLoadedState);
5018cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    }
5019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5021f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::LoadedToIdleState::allocateBuffers() {
5022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
5023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
5025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
5026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mCodec->allocateBuffersOnPort(kPortIndexOutput);
5029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5031f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
5032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
503372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
5034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
5037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
50406507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
50416507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
50426507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
50436507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
50446507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
50456507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
50466463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatResume:
50476463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
50486463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We'll be active soon enough.
50496463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
50506463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
50516463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
50526463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatFlush:
50536463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
50546463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We haven't even started yet, so we're flushed alright...
50556463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            sp<AMessage> notify = mCodec->mNotify->dup();
5056d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
50576463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->post();
50586463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
50596463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
50606463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
5061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
5063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5066f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onOMXEvent(
5067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
5072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
5073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
5075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting),
5076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
5077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mIdleToExecutingState);
5079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5081f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5086f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5089f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5090f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
5091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5094f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToExecutingState::stateEntered() {
50953856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
5096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5098f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
5099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
510072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
5101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
5104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5107d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatResume:
5108d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
5109d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We'll be active soon enough.
5110d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
5111d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
5112d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
5113d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatFlush:
5114d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
5115d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We haven't even started yet, so we're flushed alright...
5116d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
5117d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
5118d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->post();
5119d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
5120d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
5121d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
5122d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
51236507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
51246507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
51256507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
51266507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
51276507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
51286507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
5129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
5131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5134f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onOMXEvent(
5135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
5140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateExecuting);
5141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mExecutingState->resume();
5143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingState);
5144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5155f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingState::ExecutingState(ACodec *codec)
5156349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    : BaseState(codec),
5157349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber      mActive(false) {
5158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5160f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
5161ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
5162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
5163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5165054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputMetaBuffers() {
5166054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // submit as many buffers as there are input buffers with the codec
5167054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // in case we are in port reconfiguring
5168054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
5169054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
5170054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5171054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) {
5172054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            if (mCodec->submitOutputMetaDataBuffer() != OK)
5173054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                break;
5174054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
5175054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
51764dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
51774dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
51784dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
5179054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
5180054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5181054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitRegularOutputBuffers() {
5182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
5183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
5184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mCodec->mNativeWindow != NULL) {
5186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(info->mStatus == BufferInfo::OWNED_BY_US
5187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
5188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
5190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                continue;
5191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
5193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
5194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
51963856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] calling fillBuffer %p",
5197349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str(), info->mBufferID);
5198349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
5200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
5201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
5203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5206054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputBuffers() {
5207c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar    submitRegularOutputBuffers();
5208054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mCodec->mStoreMetaDataInOutputBuffers) {
5209054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        submitOutputMetaBuffers();
5210054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
5211054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
5212054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5213f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::resume() {
5214349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    if (mActive) {
52153856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] We're already active, no need to resume.",
5216349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str());
5217349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5218349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        return;
5219349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    }
5220349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    submitOutputBuffers();
5222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
52233cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    // Post all available input buffers
5224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_GT(mCodec->mBuffers[kPortIndexInput].size(), 0u);
52253cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); i++) {
52263cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
52273cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_US) {
52283cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar            postFillThisBuffer(info);
52293cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        }
52303cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    }
5231349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5232349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    mActive = true;
5233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5235f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::stateEntered() {
52363856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
5237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->processDeferredMessages();
5239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5241f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
5242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5247c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
5248c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
5249c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
5250c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5251c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mShutdownInProgress = true;
525254b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
5253c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mKeepComponentAllocated = keepComponentAllocated;
5254c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5255349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
5256349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
5258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
5259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
5260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingToIdleState);
5262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
52697a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong            ALOGV("[%s] ExecutingState flushing now "
5270d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                 "(codec owns %d/%d input, %d/%d output).",
5271d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mComponentName.c_str(),
5272d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
5273d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexInput].size(),
5274d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
5275d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexOutput].size());
5276d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
5277349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
5278349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
5280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandFlush, OMX_ALL),
5281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
5282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mFlushingState);
5284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatResume:
5289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            resume();
5291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5296496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
5297496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
5298496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            status_t err = mCodec->requestIDRFrame();
5299496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            if (err != OK) {
5300496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                ALOGW("Requesting an IDR frame failed.");
5301496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            }
5302496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5303496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            handled = true;
5304496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
5305496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
5306496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5307a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
5308a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
5309a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
5310a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
5311a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5312a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = mCodec->setParameters(params);
5313a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5314a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> reply;
5315a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            if (msg->findMessage("reply", &reply)) {
5316a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->setInt32("err", err);
5317a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->post();
5318a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            }
5319a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5320a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            handled = true;
5321a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
5322a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
5323a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
53247cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
53257cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
53266507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
53277cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
53287cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
53297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
53307cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
53314dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
53324dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        case kWhatSubmitOutputMetaDataBufferIfEOS:
53334dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        {
53344dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            if (mCodec->mPortEOS[kPortIndexInput] &&
53354dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    !mCodec->mPortEOS[kPortIndexOutput]) {
53364dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                status_t err = mCodec->submitOutputMetaDataBuffer();
53374dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                if (err == OK) {
53384dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
53394dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                }
53404dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            }
53414dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            return true;
53424dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        }
53434dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
5344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5352a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t ACodec::setParameters(const sp<AMessage> &params) {
5353a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    int32_t videoBitrate;
5354530fdbdc1b5491f3fbf172752834d1515701e142Lajos Molnar    if (params->findInt32("video-bitrate", &videoBitrate)) {
5355a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        OMX_VIDEO_CONFIG_BITRATETYPE configParams;
5356a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        InitOMXParams(&configParams);
5357a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nPortIndex = kPortIndexOutput;
5358a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nEncodeBitrate = videoBitrate;
5359a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5360a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        status_t err = mOMX->setConfig(
5361a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                mNode,
5362a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                OMX_IndexConfigVideoBitrate,
5363a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                &configParams,
5364a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                sizeof(configParams));
5365a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5366a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        if (err != OK) {
5367a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
5368a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                   videoBitrate, err);
5369a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5370a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            return err;
5371a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
5372a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    }
5373a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
537472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    int64_t skipFramesBeforeUs;
537572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (params->findInt64("skip-frames-before", &skipFramesBeforeUs)) {
537672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        status_t err =
537772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mOMX->setInternalOption(
537872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     mNode,
537972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     kPortIndexInput,
538072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     IOMX::INTERNAL_OPTION_START_TIME,
538172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     &skipFramesBeforeUs,
538272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     sizeof(skipFramesBeforeUs));
538372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
538472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
538572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("Failed to set parameter 'skip-frames-before' (err %d)", err);
538672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            return err;
538772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
538872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
538972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
5390e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    int32_t dropInputFrames;
5391e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    if (params->findInt32("drop-input-frames", &dropInputFrames)) {
5392e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        bool suspend = dropInputFrames != 0;
5393e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
5394b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err =
5395b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            mOMX->setInternalOption(
5396e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     mNode,
5397e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     kPortIndexInput,
5398e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     IOMX::INTERNAL_OPTION_SUSPEND,
5399e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     &suspend,
5400b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber                     sizeof(suspend));
5401b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
5402b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
5403b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err);
5404b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
5405b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
5406b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    }
5407b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
5408b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    int32_t dummy;
5409b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    if (params->findInt32("request-sync", &dummy)) {
5410b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err = requestIDRFrame();
5411b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
5412b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
5413b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Requesting a sync frame failed w/ err %d", err);
5414b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
5415b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
5416e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    }
5417e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
5418a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return OK;
5419a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
5420a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
54216507d14c6d10f93d390de62b9eed267f9b544985Andy McFaddenvoid ACodec::onSignalEndOfInputStream() {
54226507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    sp<AMessage> notify = mNotify->dup();
5423d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatSignaledInputEOS);
54246507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
54256507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    status_t err = mOMX->signalEndOfInputStream(mNode);
54266507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    if (err != OK) {
54276507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        notify->setInt32("err", err);
54286507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    }
54296507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->post();
54306507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden}
54316507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
5432f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onOMXEvent(
5433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventPortSettingsChanged:
5436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
5438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
543931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
5440054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mCodec->mMetaDataBuffersToSubmit = 0;
5441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
5442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
5443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_CommandPortDisable, kPortIndexOutput),
5444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
5445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5446349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                mCodec->freeOutputBuffersNotOwnedByComponent();
5447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
544931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            } else if (data2 == OMX_IndexConfigCommonOutputCrop) {
545031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
5451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
54523856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08lx",
5453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->mComponentName.c_str(), data2);
5454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventBufferFlag:
5460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5471f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
5472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ACodec *codec)
5473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5476f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
5477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
5478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput) {
5479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return FREE_BUFFERS;
5480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
5483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
5485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5487f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onMessageReceived(
5488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
5489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5494349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case kWhatResume:
5495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5496349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            if (msg->what() == kWhatResume) {
54973856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
5498349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            }
5499349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
5501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5513f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::OutputPortSettingsChangedState::stateEntered() {
55143856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now handling output port settings change",
5515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mCodec->mComponentName.c_str());
5516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5518f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onOMXEvent(
5519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
5524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
5525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
55263856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now disabled.",
5527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
5528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mCodec->mBuffers[kPortIndexOutput].isEmpty());
5530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mDealer[kPortIndexOutput].clear();
5531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
5533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput),
5534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
5535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5536cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                status_t err;
5537cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                if ((err = mCodec->allocateBuffersOnPort(
5538cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                                kPortIndexOutput)) != OK) {
553929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("Failed to allocate output port buffers after "
5540cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         "port reconfiguration (error 0x%08x)",
5541cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         err);
5542cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
5543251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5544d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
5545755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // This is technically not correct, but appears to be
5546755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the only way to free the component instance.
5547755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // Controlled transitioning from excecuting->idle
5548755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // and idle->loaded seem impossible probably because
5549755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the output port never finishes re-enabling.
5550755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mShutdownInProgress = true;
5551755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mKeepComponentAllocated = false;
5552755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->changeState(mCodec->mLoadedState);
5553cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                }
5554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
5556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
5557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
5558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
555931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
556031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
55613856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now reenabled.",
5562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
5563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5564349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                if (mCodec->mExecutingState->active()) {
5565349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    mCodec->mExecutingState->submitOutputBuffers();
5566349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                }
5567349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mExecutingState);
5569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
5571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
5574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
5578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5583f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
55845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : BaseState(codec),
55855778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mComponentNowIdle(false) {
5586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5588f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
5589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
5595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
5596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
5597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
5603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5616f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::stateEntered() {
56173856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
561831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
56195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mComponentNowIdle = false;
562031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mCodec->mSentFormat = false;
5621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5623f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onOMXEvent(
5624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
5629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
5630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
56315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mComponentNowIdle = true;
56325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            changeStateIfWeOwnAllBuffers();
5634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5638349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
5639349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventBufferFlag:
5640349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
5641349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We're shutting down and don't care about this anymore.
5642349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
5643349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
5644349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
56490af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
5650f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
56515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
5652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->sendCommand(
5653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded),
5654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
5655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexInput), (status_t)OK);
5657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexOutput), (status_t)OK);
5658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
56590167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown)
56600167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && mCodec->mNativeWindow != NULL) {
5661bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // We push enough 1x1 blank buffers to ensure that one of
5662bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // them has made it to the display.  This allows the OMX
5663bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // component teardown to zero out any protected buffers
5664bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // without the risk of scanning out one of those buffers.
5665bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            mCodec->pushBlankBuffersToNativeWindow();
5666bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
5667bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
5668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mIdleToLoadedState);
5669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5672f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onInputBufferFilled(
5673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
5674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
5675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
5677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5679f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onOutputBufferDrained(
5680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
5681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
5682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
5684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5688f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
5689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5692f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
5693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
5699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
5707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
5708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
5709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5720f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToLoadedState::stateEntered() {
57213856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
5722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5724f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onOMXEvent(
5725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
5730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateLoaded);
5731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5732c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->changeState(mCodec->mLoadedState);
5733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5744f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::FlushingState::FlushingState(ACodec *codec)
5745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5748f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::stateEntered() {
57493856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
5750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
5752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5754f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
5755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
5761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing this right now.
5767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5775f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5779f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onOMXEvent(
5780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
57817a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] FlushingState onOMXEvent(%d,%ld)",
5782d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            mCodec->mComponentName.c_str(), event, data1);
5783d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
5784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandFlush);
5788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
5790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(!mFlushComplete[data2]);
5791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mFlushComplete[data2] = true;
5792e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber
5793e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                if (mFlushComplete[kPortIndexInput]
5794e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                        && mFlushComplete[kPortIndexOutput]) {
5795e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                    changeStateIfWeOwnAllBuffers();
5796e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                }
5797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
5798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, OMX_ALL);
5799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexInput]);
5800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexOutput]);
5801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                changeStateIfWeOwnAllBuffers();
5803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5808349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
5809349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
5810349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec->id());
5811349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("type", omx_message::EVENT);
5812609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            msg->setInt32("node", mCodec->mNode);
5813349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("event", event);
5814349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data1", data1);
5815349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data2", data2);
5816349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
58173856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
5818349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                 mCodec->mComponentName.c_str());
5819349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5820349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mCodec->deferMessage(msg);
5821349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5822349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
5823349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
5824349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
5830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5832f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
5833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
5834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
5836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5838f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
5839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
5840f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
5842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5844f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
5845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mFlushComplete[kPortIndexInput]
5846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mFlushComplete[kPortIndexOutput]
5847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mCodec->allYourBuffersAreBelongToUs()) {
58487e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // We now own all buffers except possibly those still queued with
58497e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // the native window for rendering. Let's get those back as well.
58507e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
58517e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
5852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
5853d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatFlushCompleted);
5854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->post();
5855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->mPortEOS[kPortIndexInput] =
5857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mPortEOS[kPortIndexOutput] = false;
5858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5859dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber        mCodec->mInputEOSResult = OK;
5860dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
5861f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        if (mCodec->mSkipCutBuffer != NULL) {
5862f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen            mCodec->mSkipCutBuffer->clear();
5863f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        }
5864f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen
5865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mExecutingState);
5866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
5870