ACodec.cpp revision a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5
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
673bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (mFlags & kFlagIsSecure) {
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" },
1109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
1110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const size_t kNumMimeToRole =
1112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
1113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    size_t i;
1115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (i = 0; i < kNumMimeToRole; ++i) {
1116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcasecmp(mime, kMimeToRole[i].mime)) {
1117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (i == kNumMimeToRole) {
11225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_UNSUPPORTED;
1123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    const char *role =
1126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        isEncoder ? kMimeToRole[i].encoderRole
1127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                  : kMimeToRole[i].decoderRole;
1128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (role != NULL) {
1130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_PARAM_COMPONENTROLETYPE roleParams;
1131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        InitOMXParams(&roleParams);
1132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        strncpy((char *)roleParams.cRole,
1134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                role, OMX_MAX_STRINGNAME_SIZE - 1);
1135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
1137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->setParameter(
1139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamStandardComponentRole,
1140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &roleParams, sizeof(roleParams));
1141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
11435ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("[%s] Failed to set standard component role '%s'.",
1144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 mComponentName.c_str(), role);
11455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
1147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
11495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
1151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
11535778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::configureCodec(
1154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime, const sp<AMessage> &msg) {
11555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t encoder;
11565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("encoder", &encoder)) {
11575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        encoder = false;
11585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1160e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    sp<AMessage> inputFormat = new AMessage();
11614e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    sp<AMessage> outputFormat = mNotify->dup(); // will use this for kWhatOutputFormatChanged
1162e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
11635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mIsEncoder = encoder;
1164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
11655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setComponentRole(encoder /* isEncoder */, mime);
11665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
11685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
11695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
11705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitRate = 0;
11722f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    // FLAC encoder doesn't need a bitrate, other encoders do
11732f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
11742f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            && !msg->findInt32("bitrate", &bitRate)) {
11755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
11765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
11775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1178d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    int32_t storeMeta;
1179d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (encoder
1180d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && msg->findInt32("store-metadata-in-buffers", &storeMeta)
1181d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && storeMeta != 0) {
1182d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE);
1183d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1184d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (err != OK) {
1185308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              ALOGE("[%s] storeMetaDataInBuffers (input) failed w/ err %d",
1186308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    mComponentName.c_str(), err);
1187d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1188308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              return err;
1189308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang          }
1190308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang      }
1191d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1192308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t prependSPSPPS = 0;
11933a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    if (encoder
11943a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
11953a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && prependSPSPPS != 0) {
11963a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        OMX_INDEXTYPE index;
11973a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        err = mOMX->getExtensionIndex(
11983a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                mNode,
11993a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                "OMX.google.android.index.prependSPSPPSToIDRFrames",
12003a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                &index);
12013a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
12023a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err == OK) {
12033a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            PrependSPSPPSToIDRFramesParams params;
12043a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            InitOMXParams(&params);
12053a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            params.bEnable = OMX_TRUE;
12063a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
12073a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            err = mOMX->setParameter(
12083a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                    mNode, index, &params, sizeof(params));
12093a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
12103a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
12113a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err != OK) {
12123a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            ALOGE("Encoder could not be configured to emit SPS/PPS before "
12133a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                  "IDR frames. (err %d)", err);
12143a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
12153a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            return err;
12163a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
12173a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    }
12183a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
1219308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // Only enable metadata mode on encoder output if encoder can prepend
1220308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // sps/pps to idr frames, since in metadata mode the bitstream is in an
1221308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // opaque handle, to which we don't have access.
1222308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t video = !strncasecmp(mime, "video/", 6);
1223308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (encoder && video) {
1224308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS
1225308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && msg->findInt32("store-metadata-in-buffers-output", &storeMeta)
1226308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && storeMeta != 0);
1227308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1228308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, enable);
1229308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1230308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        if (err != OK) {
1231308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            ALOGE("[%s] storeMetaDataInBuffers (output) failed w/ err %d",
1232308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                mComponentName.c_str(), err);
1233308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = 0;
1234308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        } else {
1235308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = enable;
1236308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        }
1237a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
1238a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (!msg->findInt64(
1239a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    "repeat-previous-frame-after",
1240a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    &mRepeatFrameDelayUs)) {
1241a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            mRepeatFrameDelayUs = -1ll;
1242a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
124394ee4b708acfa941581160b267afb79192b1d816Chong Zhang
124494ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (!msg->findInt64("max-pts-gap-to-encoder", &mMaxPtsGapUs)) {
12452c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mMaxPtsGapUs = -1ll;
12462c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
12472c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
12482c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (!msg->findInt64("time-lapse", &mTimePerCaptureUs)) {
12492c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mTimePerCaptureUs = -1ll;
125094ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
125172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
125272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (!msg->findInt32(
125372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    "create-input-buffers-suspended",
125472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    (int32_t*)&mCreateInputBuffersSuspended)) {
125572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mCreateInputBuffersSuspended = false;
125672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
1257308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    }
1258308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1259054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    sp<RefBase> obj;
1260054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    int32_t haveNativeWindow = msg->findObject("native-window", &obj) &&
12615a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        obj != NULL;
1262054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mStoreMetaDataInOutputBuffers = false;
1263e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if (video && !encoder) {
1264e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        inputFormat->setInt32("adaptive-playback", false);
1265e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
1266054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (!encoder && video && haveNativeWindow) {
12675a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        sp<NativeWindowWrapper> windowWrapper(
12685a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                static_cast<NativeWindowWrapper *>(obj.get()));
12695a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        sp<ANativeWindow> nativeWindow = windowWrapper->getNativeWindow();
12705a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
12716597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        // START of temporary support for automatic FRC - THIS WILL BE REMOVED
12726597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        int32_t autoFrc;
12736597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        if (msg->findInt32("auto-frc", &autoFrc)) {
12746597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            bool enabled = autoFrc;
12756597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            OMX_CONFIG_BOOLEANTYPE config;
12766597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            InitOMXParams(&config);
12776597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            config.bEnabled = (OMX_BOOL)enabled;
12786597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            status_t temp = mOMX->setConfig(
12796597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                    mNode, (OMX_INDEXTYPE)OMX_IndexConfigAutoFramerateConversion,
12806597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                    &config, sizeof(config));
12816597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            if (temp == OK) {
12826597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                outputFormat->setInt32("auto-frc", enabled);
12836597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            } else if (enabled) {
12846597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                ALOGI("codec does not support requested auto-frc (err %d)", temp);
12856597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            }
12866597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        }
12876597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        // END of temporary support for automatic FRC
12886597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar
12895a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        int32_t tunneled;
12905a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        if (msg->findInt32("feature-tunneled-playback", &tunneled) &&
12915a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            tunneled != 0) {
12925a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            ALOGI("Configuring TUNNELED video playback.");
1293ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            mTunneled = true;
12945a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
129597827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad            int32_t audioHwSync = 0;
129697827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad            if (!msg->findInt32("audio-hw-sync", &audioHwSync)) {
12975a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGW("No Audio HW Sync provided for video tunnel");
12985a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            }
12995a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            err = configureTunneledVideoPlayback(audioHwSync, nativeWindow);
13005a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (err != OK) {
130197827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad                ALOGE("configureTunneledVideoPlayback(%d,%p) failed!",
13025a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        audioHwSync, nativeWindow.get());
13035a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                return err;
1304fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
1305fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
13065a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            inputFormat->setInt32("adaptive-playback", true);
13075a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        } else {
1308ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            ALOGV("Configuring CPU controlled video playback.");
1309ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            mTunneled = false;
1310ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
13115a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            // Always try to enable dynamic output buffers on native surface
13125a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            err = mOMX->storeMetaDataInBuffers(
13135a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    mNode, kPortIndexOutput, OMX_TRUE);
13145a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (err != OK) {
13155a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d",
1316fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        mComponentName.c_str(), err);
1317e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
13185a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // if adaptive playback has been requested, try JB fallback
13195a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // NOTE: THIS FALLBACK MECHANISM WILL BE REMOVED DUE TO ITS
13205a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // LARGE MEMORY REQUIREMENT
13215a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
13225a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // we will not do adaptive playback on software accessed
13235a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // surfaces as they never had to respond to changes in the
13245a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // crop window, and we don't trust that they will be able to.
13255a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                int usageBits = 0;
13265a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                bool canDoAdaptivePlayback;
13275a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
13285a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                if (nativeWindow->query(
13295a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        nativeWindow.get(),
13305a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        NATIVE_WINDOW_CONSUMER_USAGE_BITS,
13315a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        &usageBits) != OK) {
13325a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    canDoAdaptivePlayback = false;
13335a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                } else {
13345a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    canDoAdaptivePlayback =
13355a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        (usageBits &
13365a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                                (GRALLOC_USAGE_SW_READ_MASK |
13375a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                                 GRALLOC_USAGE_SW_WRITE_MASK)) == 0;
13385a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                }
13395a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
13405a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                int32_t maxWidth = 0, maxHeight = 0;
13415a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                if (canDoAdaptivePlayback &&
13425a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        msg->findInt32("max-width", &maxWidth) &&
13435a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        msg->findInt32("max-height", &maxHeight)) {
13445a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    ALOGV("[%s] prepareForAdaptivePlayback(%dx%d)",
13455a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mComponentName.c_str(), maxWidth, maxHeight);
13465a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
13475a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    err = mOMX->prepareForAdaptivePlayback(
13485a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mNode, kPortIndexOutput, OMX_TRUE, maxWidth,
13495a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            maxHeight);
13505a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    ALOGW_IF(err != OK,
13515a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            "[%s] prepareForAdaptivePlayback failed w/ err %d",
13525a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mComponentName.c_str(), err);
13535a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
13545a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    if (err == OK) {
13555a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("max-width", maxWidth);
13565a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("max-height", maxHeight);
13575a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("adaptive-playback", true);
13585a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    }
1359e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
13605a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // allow failure
13615a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                err = OK;
13625a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            } else {
13635a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGV("[%s] storeMetaDataInBuffers succeeded",
13645a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        mComponentName.c_str());
13655a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                mStoreMetaDataInOutputBuffers = true;
13665a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                inputFormat->setInt32("adaptive-playback", true);
1367fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
13680167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber
13695a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            int32_t push;
13705a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (msg->findInt32("push-blank-buffers-on-shutdown", &push)
13715a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    && push != 0) {
13725a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
13735a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            }
13740167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        }
1375e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang
1376e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        int32_t rotationDegrees;
1377e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        if (msg->findInt32("rotation-degrees", &rotationDegrees)) {
1378e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            mRotationDegrees = rotationDegrees;
1379e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        } else {
1380e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            mRotationDegrees = 0;
1381e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        }
1382054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1383054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1384308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (video) {
13855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (encoder) {
13865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupVideoEncoder(mime, msg);
13875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
138889869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            err = setupVideoDecoder(mime, msg);
13895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
139042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
139142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        int32_t numChannels, sampleRate;
139242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        if (!msg->findInt32("channel-count", &numChannels)
139342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
139442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // Since we did not always check for these, leave them optional
139542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // and have the decoder figure it all out.
139642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = OK;
139742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        } else {
139842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = setupRawAudioFormat(
139942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    encoder ? kPortIndexInput : kPortIndexOutput,
140042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    sampleRate,
140142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    numChannels);
140242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        }
1403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
1404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t numChannels, sampleRate;
14055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)
14065778822d86b0337407514b9372562b86edfa91cdAndreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
14075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
14085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
1409aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            int32_t isADTS, aacProfile;
1410b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            int32_t sbrMode;
14118045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            int32_t maxOutputChannelCount;
14122965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            int32_t pcmLimiterEnable;
14138045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            drcParams_t drc;
1414ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            if (!msg->findInt32("is-adts", &isADTS)) {
1415ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                isADTS = 0;
1416ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
1417aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (!msg->findInt32("aac-profile", &aacProfile)) {
1418aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                aacProfile = OMX_AUDIO_AACObjectNull;
1419aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
1420b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            if (!msg->findInt32("aac-sbr-mode", &sbrMode)) {
1421b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                sbrMode = -1;
1422b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            }
1423ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
14248045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-max-output-channel_count", &maxOutputChannelCount)) {
14258045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                maxOutputChannelCount = -1;
14268045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
14272965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            if (!msg->findInt32("aac-pcm-limiter-enable", &pcmLimiterEnable)) {
14282965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                // value is unknown
14292965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                pcmLimiterEnable = -1;
14302965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            }
14318045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-encoded-target-level", &drc.encodedTargetLevel)) {
14328045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
14338045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.encodedTargetLevel = -1;
14348045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
14358045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-cut-level", &drc.drcCut)) {
14368045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
14378045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.drcCut = -1;
14388045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
14398045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-boost-level", &drc.drcBoost)) {
14408045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
14418045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.drcBoost = -1;
14428045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
14438045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-heavy-compression", &drc.heavyCompression)) {
14448045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
14458045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.heavyCompression = -1;
14468045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
14478045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-target-ref-level", &drc.targetRefLevel)) {
14488045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
14498045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.targetRefLevel = -1;
14508045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
14518045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi
1452ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            err = setupAACCodec(
14534471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    encoder, numChannels, sampleRate, bitRate, aacProfile,
14542965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                    isADTS != 0, sbrMode, maxOutputChannelCount, drc,
14552965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                    pcmLimiterEnable);
14565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
1457729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
14585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
1459729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
14605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
1461729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
1462729de186450f78c099637e1fce743fe531862c52Andreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
1463729de186450f78c099637e1fce743fe531862c52Andreas Huber        // These are PCM-like formats with a fixed sample rate but
1464729de186450f78c099637e1fce743fe531862c52Andreas Huber        // a variable number of channels.
1465729de186450f78c099637e1fce743fe531862c52Andreas Huber
1466729de186450f78c099637e1fce743fe531862c52Andreas Huber        int32_t numChannels;
14675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)) {
14685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
14695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
14705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupG711Codec(encoder, numChannels);
14715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14722f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
14732f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        int32_t numChannels, sampleRate, compressionLevel = -1;
14742f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (encoder &&
14752f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                (!msg->findInt32("channel-count", &numChannels)
14762f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                        || !msg->findInt32("sample-rate", &sampleRate))) {
14772f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("missing channel count or sample rate for FLAC encoder");
14782f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            err = INVALID_OPERATION;
14792f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        } else {
14802f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            if (encoder) {
1481516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                if (!msg->findInt32(
1482cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                            "complexity", &compressionLevel) &&
1483cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                    !msg->findInt32(
1484516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                            "flac-compression-level", &compressionLevel)) {
1485cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                    compressionLevel = 5; // default FLAC compression level
14862f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel < 0) {
1487516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1488516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 0",
1489516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
14902f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 0;
14912f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel > 8) {
1492516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1493516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 8",
1494516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
14952f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 8;
14962f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                }
14972f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            }
1498516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            err = setupFlacCodec(
1499516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    encoder, numChannels, sampleRate, compressionLevel);
15002f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
1501ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
1502ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        int32_t numChannels, sampleRate;
1503ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        if (encoder
1504ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("channel-count", &numChannels)
1505ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
1506ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = INVALID_OPERATION;
1507ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        } else {
1508ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
1509ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        }
151097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AC3)) {
151197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t numChannels;
151297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t sampleRate;
151397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        if (!msg->findInt32("channel-count", &numChannels)
151497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                || !msg->findInt32("sample-rate", &sampleRate)) {
151597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = INVALID_OPERATION;
151697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        } else {
151797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = setupAC3Codec(encoder, numChannels, sampleRate);
151897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        }
15195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1520729de186450f78c099637e1fce743fe531862c52Andreas Huber
15214471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    if (err != OK) {
15224471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber        return err;
15234471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    }
15244471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber
15258b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
15268b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderDelay = 0;
15278b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
15289806555d3930be43e11106281dee354820ac1c88Andreas Huber
15298b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
15308b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderPadding = 0;
15318b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
15328b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen
15339806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (msg->findInt32("channel-mask", &mChannelMask)) {
15349806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = true;
15359806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else {
15369806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = false;
15379806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
15389806555d3930be43e11106281dee354820ac1c88Andreas Huber
1539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t maxInputSize;
1540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (msg->findInt32("max-input-size", &maxInputSize)) {
15415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
1542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
15435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
1544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
15455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15464e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    mBaseOutputFormat = outputFormat;
15474e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar
1548e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ(getPortFormat(kPortIndexInput, inputFormat), (status_t)OK);
1549e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ(getPortFormat(kPortIndexOutput, outputFormat), (status_t)OK);
1550e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mInputFormat = inputFormat;
1551e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mOutputFormat = outputFormat;
1552e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
15535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
1554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1556f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
1557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
1559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
1560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (def.nBufferSize >= size) {
1569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
1570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nBufferSize = size;
1573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
1575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->getParameter(
1582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(def.nBufferSize >= size);
1589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
15935778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::selectAudioPortFormat(
15945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
15955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_AUDIO_PARAM_PORTFORMATTYPE format;
15965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&format);
15975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    format.nPortIndex = portIndex;
15995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (OMX_U32 index = 0;; ++index) {
16005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        format.nIndex = index;
16015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
16035778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioPortFormat,
16045778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &format, sizeof(format));
16055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
16075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
16085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (format.eEncoding == desiredFormat) {
16115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
16125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
16165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format));
16175778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
16185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16195778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAACCodec(
1620aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        bool encoder, int32_t numChannels, int32_t sampleRate,
16218045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        int32_t bitRate, int32_t aacProfile, bool isADTS, int32_t sbrMode,
16222965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang        int32_t maxOutputChannelCount, const drcParams_t& drc,
16232965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang        int32_t pcmLimiterEnable) {
1624ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (encoder && isADTS) {
1625ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return -EINVAL;
1626ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
1627ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
16285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setupRawAudioFormat(
16295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
16305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sampleRate,
16315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            numChannels);
16325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
16345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
16355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (encoder) {
16385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
16395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
16415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
16425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
16455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
16465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = kPortIndexOutput;
16475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
16495778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
16505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
16525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
16535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.bFlagErrorConcealment = OMX_TRUE;
16565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
16575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
16595778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
16605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
16625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
16635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
16665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&profile);
16675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nPortIndex = kPortIndexOutput;
16685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
16705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
16715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
16735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
16745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nChannels = numChannels;
16775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eChannelMode =
16795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (numChannels == 1)
16805778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
16815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nSampleRate = sampleRate;
16835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nBitRate = bitRate;
16845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAudioBandWidth = 0;
16855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nFrameLength = 0;
16865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACtools = OMX_AUDIO_AACToolAll;
16875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACERtools = OMX_AUDIO_AACERNone;
1688aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
16895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
1690b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        switch (sbrMode) {
1691b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 0:
1692b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // disable sbr
1693b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
1694b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
1695b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
1696b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 1:
1697b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable single-rate sbr
1698b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
1699b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
1700b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
1701b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 2:
1702b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable dual-rate sbr
1703b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
1704b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
1705b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
1706b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case -1:
1707b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable both modes -> the codec will decide which mode should be used
1708b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
1709b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
1710b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
1711b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        default:
1712b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // unsupported sbr mode
1713b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            return BAD_VALUE;
1714b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        }
1715b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi
17165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
17185778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
17195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
17215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
17225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
17255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_AUDIO_PARAM_AACPROFILETYPE profile;
1728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&profile);
1729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nPortIndex = kPortIndexInput;
1730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
17315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
1732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
1733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nChannels = numChannels;
1739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nSampleRate = sampleRate;
1740ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1741ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    profile.eAACStreamFormat =
1742ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        isADTS
1743ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            ? OMX_AUDIO_AACStreamFormatMP4ADTS
1744ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            : OMX_AUDIO_AACStreamFormatMP4FF;
1745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
17468045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    OMX_AUDIO_PARAM_ANDROID_AACPRESENTATIONTYPE presentation;
17478045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nMaxOutputChannels = maxOutputChannelCount;
17488045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nDrcCut = drc.drcCut;
17498045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nDrcBoost = drc.drcBoost;
17508045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nHeavyCompression = drc.heavyCompression;
17518045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nTargetReferenceLevel = drc.targetRefLevel;
17528045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nEncodedTargetLevel = drc.encodedTargetLevel;
17532965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang    presentation.nPCMLimiterEnable = pcmLimiterEnable;
17548045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi
17558045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    status_t res = mOMX->setParameter(mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
17568045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    if (res == OK) {
17578045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        // optional parameters, will not cause configuration failure
17588045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        mOMX->setParameter(mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAacPresentation,
17598045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                &presentation, sizeof(presentation));
17608045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    } else {
17618045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        ALOGW("did not set AudioAndroidAacPresentation due to error %d when setting AudioAac", res);
17628045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    }
17638045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    return res;
17645778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
176697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryustatus_t ACodec::setupAC3Codec(
176797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        bool encoder, int32_t numChannels, int32_t sampleRate) {
176897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    status_t err = setupRawAudioFormat(
176997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
177097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
177197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
177297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
177397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
177497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
177597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (encoder) {
177697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        ALOGW("AC3 encoding is not supported.");
177797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return INVALID_OPERATION;
177897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
177997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
178097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    OMX_AUDIO_PARAM_ANDROID_AC3TYPE def;
178197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    InitOMXParams(&def);
178297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nPortIndex = kPortIndexInput;
178397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
178497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    err = mOMX->getParameter(
178597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
178697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
178797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
178897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
178997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
179097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
179197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
179297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
179397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
179497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nChannels = numChannels;
179597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nSampleRate = sampleRate;
179697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
179797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    return mOMX->setParameter(
179897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
179997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
180097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
180197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
180297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu}
180397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
18045778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
18055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        bool isAMRWB, int32_t bps) {
18065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (isAMRWB) {
18075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 6600) {
18085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB0;
18095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 8850) {
18105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB1;
18115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 12650) {
18125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB2;
18135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 14250) {
18145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB3;
18155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 15850) {
18165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB4;
18175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 18250) {
18185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB5;
18195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 19850) {
18205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB6;
18215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 23050) {
18225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB7;
18235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 23850 bps
18265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeWB8;
18275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {  // AMRNB
18285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 4750) {
18295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB0;
18305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5150) {
18315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB1;
18325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5900) {
18335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB2;
18345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 6700) {
18355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB3;
18365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7400) {
18375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB4;
18385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7950) {
18395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB5;
18405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 10200) {
18415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB6;
18425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 12200 bps
18455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeNB7;
18465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
18495778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
1850729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_AMRTYPE def;
1851729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
18525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
1853729de186450f78c099637e1fce743fe531862c52Andreas Huber
1854729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err =
1855729de186450f78c099637e1fce743fe531862c52Andreas Huber        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1856729de186450f78c099637e1fce743fe531862c52Andreas Huber
1857729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1858729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1859729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1860729de186450f78c099637e1fce743fe531862c52Andreas Huber
1861729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
18625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
18635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
18655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1866729de186450f78c099637e1fce743fe531862c52Andreas Huber
18675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1870729de186450f78c099637e1fce743fe531862c52Andreas Huber
18715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupRawAudioFormat(
18725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
18735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            isWAMR ? 16000 : 8000 /* sampleRate */,
18745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            1 /* numChannels */);
1875729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1876729de186450f78c099637e1fce743fe531862c52Andreas Huber
18775778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupG711Codec(bool encoder, int32_t numChannels) {
18785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(!encoder);  // XXX TODO
18795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1880729de186450f78c099637e1fce743fe531862c52Andreas Huber    return setupRawAudioFormat(
1881729de186450f78c099637e1fce743fe531862c52Andreas Huber            kPortIndexInput, 8000 /* sampleRate */, numChannels);
1882729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1883729de186450f78c099637e1fce743fe531862c52Andreas Huber
18842f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivistatus_t ACodec::setupFlacCodec(
18852f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
18862f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
18872f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder) {
18882f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        OMX_AUDIO_PARAM_FLACTYPE def;
18892f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        InitOMXParams(&def);
18902f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nPortIndex = kPortIndexOutput;
18912f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
18922f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        // configure compression level
18932f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        status_t err = mOMX->getParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
18942f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
18952f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
18962f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
18972f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
18982f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nCompressionLevel = compressionLevel;
18992f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        err = mOMX->setParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
19002f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
19012f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
19022f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
19032f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
19042f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
19052f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
19062f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    return setupRawAudioFormat(
19072f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            encoder ? kPortIndexInput : kPortIndexOutput,
19082f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            sampleRate,
19092f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            numChannels);
19102f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi}
19112f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
1912729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t ACodec::setupRawAudioFormat(
1913729de186450f78c099637e1fce743fe531862c52Andreas Huber        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
1914729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1915729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
1916729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.nPortIndex = portIndex;
1917729de186450f78c099637e1fce743fe531862c52Andreas Huber
1918729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err = mOMX->getParameter(
1919729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1920729de186450f78c099637e1fce743fe531862c52Andreas Huber
1921729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1922729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1923729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1924729de186450f78c099637e1fce743fe531862c52Andreas Huber
1925729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
1926729de186450f78c099637e1fce743fe531862c52Andreas Huber
1927729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->setParameter(
1928729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1929729de186450f78c099637e1fce743fe531862c52Andreas Huber
1930729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1931729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1932729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1933729de186450f78c099637e1fce743fe531862c52Andreas Huber
1934729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
1935729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&pcmParams);
1936729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nPortIndex = portIndex;
1937729de186450f78c099637e1fce743fe531862c52Andreas Huber
1938729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->getParameter(
1939729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1940729de186450f78c099637e1fce743fe531862c52Andreas Huber
1941729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1942729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1943729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1944729de186450f78c099637e1fce743fe531862c52Andreas Huber
1945729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nChannels = numChannels;
1946729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.eNumData = OMX_NumericalDataSigned;
1947729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.bInterleaved = OMX_TRUE;
1948729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nBitPerSample = 16;
1949729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nSamplingRate = sampleRate;
1950729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
1951729de186450f78c099637e1fce743fe531862c52Andreas Huber
1952c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber    if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
1953c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber        return OMX_ErrorNone;
1954729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1955729de186450f78c099637e1fce743fe531862c52Andreas Huber
1956729de186450f78c099637e1fce743fe531862c52Andreas Huber    return mOMX->setParameter(
1957729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1958729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1959729de186450f78c099637e1fce743fe531862c52Andreas Huber
19605a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachadstatus_t ACodec::configureTunneledVideoPlayback(
196197827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad        int32_t audioHwSync, const sp<ANativeWindow> &nativeWindow) {
19625a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    native_handle_t* sidebandHandle;
19635a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
19645a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    status_t err = mOMX->configureVideoTunnelMode(
19655a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            mNode, kPortIndexOutput, OMX_TRUE, audioHwSync, &sidebandHandle);
19665a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    if (err != OK) {
19675a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        ALOGE("configureVideoTunnelMode failed! (err %d).", err);
19685a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        return err;
19695a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    }
19705a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
19715a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    err = native_window_set_sideband_stream(nativeWindow.get(), sidebandHandle);
19725a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    if (err != OK) {
19735a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        ALOGE("native_window_set_sideband_stream(%p) failed! (err %d).",
19745a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                sidebandHandle, err);
19755a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        return err;
19765a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    }
19775a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
19785a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    return OK;
19795a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad}
19805a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
1981f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoPortFormatType(
1982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
1983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_VIDEO_CODINGTYPE compressionFormat,
1984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_COLOR_FORMATTYPE colorFormat) {
1985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
1987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = portIndex;
1988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
1989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool found = false;
1990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 index = 0;
1992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (;;) {
1993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        format.nIndex = index;
1994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->getParameter(
1995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamVideoPortFormat,
1996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &format, sizeof(format));
1997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
1999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return err;
2000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2002229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        // substitute back flexible color format to codec supported format
2003229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        OMX_U32 flexibleEquivalent;
2004229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        if (compressionFormat == OMX_VIDEO_CodingUnused &&
2005229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                isFlexibleColorFormat(
2006229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                        mOMX, mNode, format.eColorFormat, &flexibleEquivalent) &&
2007229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                colorFormat == flexibleEquivalent) {
2008229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            ALOGI("[%s] using color format %#x in place of %#x",
2009229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                    mComponentName.c_str(), format.eColorFormat, colorFormat);
2010229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            colorFormat = format.eColorFormat;
2011229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
2012229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
2013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The following assertion is violated by TI's video decoder.
2014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // CHECK_EQ(format.nIndex, index);
2015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
2017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexInput
2018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && colorFormat == format.eColorFormat) {
2019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eCompressionFormat does not seem right.
2020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
2021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
2022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexOutput
2024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && compressionFormat == format.eCompressionFormat) {
2025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eColorFormat does not seem right.
2026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
2027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
2028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (format.eCompressionFormat == compressionFormat
2032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && format.eColorFormat == colorFormat) {
2033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            found = true;
2034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ++index;
2038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!found) {
2041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return UNKNOWN_ERROR;
2042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->setParameter(
2045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
2046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
2047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
2049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2051f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setSupportedOutputFormat() {
2052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
2053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
2054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = kPortIndexOutput;
2055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
2056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
2058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
2059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
2060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
2061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)format.eCompressionFormat, (int)OMX_VIDEO_CodingUnused);
2062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mOMX->setParameter(
2064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
2065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
2066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2068e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic const struct VideoCodingMapEntry {
2069e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    const char *mMime;
2070e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    OMX_VIDEO_CODINGTYPE mVideoCodingType;
2071e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber} kVideoCodingMapEntry[] = {
2072e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC },
20732472b1c0d63454e5d90a982bd6c555de6c3127bdRachad    { MEDIA_MIMETYPE_VIDEO_HEVC, OMX_VIDEO_CodingHEVC },
2074e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 },
2075e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 },
2076e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 },
207794705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 },
207894705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 },
2079e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber};
2080e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
20815778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic status_t GetVideoCodingTypeFromMime(
20825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
2083e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
2084e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
2085e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
2086e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) {
2087e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *codingType = kVideoCodingMapEntry[i].mVideoCodingType;
2088e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
2089e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
2090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2092e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    *codingType = OMX_VIDEO_CodingUnused;
2093e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2094e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
2095e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
2096e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2097e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic status_t GetMimeTypeForVideoCoding(
2098e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        OMX_VIDEO_CODINGTYPE codingType, AString *mime) {
2099e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
2100e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
2101e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
2102e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) {
2103e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *mime = kVideoCodingMapEntry[i].mMime;
2104e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
2105e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
2106e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
2107e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2108e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    mime->clear();
2109e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2110e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
21115778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
21125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21135778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoDecoder(
211489869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        const char *mime, const sp<AMessage> &msg) {
211589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    int32_t width, height;
211689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    if (!msg->findInt32("width", &width)
211789869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            || !msg->findInt32("height", &height)) {
211889869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        return INVALID_OPERATION;
211989869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    }
212089869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar
21215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
21225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
21235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
2129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
2130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
213589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    int32_t tmp;
213689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    if (msg->findInt32("color-format", &tmp)) {
213789869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        OMX_COLOR_FORMATTYPE colorFormat =
213889869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            static_cast<OMX_COLOR_FORMATTYPE>(tmp);
213989869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        err = setVideoPortFormatType(
214089869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar                kPortIndexOutput, OMX_VIDEO_CodingUnused, colorFormat);
214189869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        if (err != OK) {
214289869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            ALOGW("[%s] does not support color format %d",
214389869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar                  mComponentName.c_str(), colorFormat);
214489869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            err = setSupportedOutputFormat();
214589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        }
214689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    } else {
214789869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        err = setSupportedOutputFormat();
214889869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    }
2149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
2155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, width, height, compressionFormat);
2156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
2162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
2163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
21715778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) {
21725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
21735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("color-format", &tmp)) {
21745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
21755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_COLOR_FORMATTYPE colorFormat =
21785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        static_cast<OMX_COLOR_FORMATTYPE>(tmp);
21795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setVideoPortFormatType(
21815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
21825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support color format %d",
21855778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str(), colorFormat);
21865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Input port configuration */
21915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
21935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&def);
21945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
21965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexInput;
21985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
22005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
22015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t width, height, bitrate;
22075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("width", &width)
22085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("height", &height)
22095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("bitrate", &bitrate)) {
22105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
22115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
22145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
22155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t stride;
22175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("stride", &stride)) {
22185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        stride = width;
22195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nStride = stride;
22225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t sliceHeight;
22245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("slice-height", &sliceHeight)) {
22255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sliceHeight = height;
22265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nSliceHeight = sliceHeight;
22295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
22315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
22335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
22345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
22355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
22365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
22375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
22392c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        mTimePerFrameUs = (int64_t) (1000000.0f / frameRate);
22405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
22435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
2244a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    // this is redundant as it was already set up in setVideoPortFormatType
2245a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    // FIXME for now skip this only for flexible YUV formats
2246a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    if (colorFormat != OMX_COLOR_FormatYUV420Flexible) {
2247a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar        video_def->eColorFormat = colorFormat;
2248a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    }
22495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
22515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
22525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set input port definition parameters.",
22555778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
22565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Output port configuration */
22615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
22635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
22645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
22705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
22715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support compression format %d",
22745778822d86b0337407514b9372562b86edfa91cdAndreas Huber             mComponentName.c_str(), compressionFormat);
22755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexOutput;
22805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
22825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
22835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
22895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
22905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = 0;
22915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nBitrate = bitrate;
22925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = compressionFormat;
22935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = OMX_COLOR_FormatUnused;
22945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
22965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
22975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set output port definition parameters.",
23005778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
23015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
23035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (compressionFormat) {
23065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingMPEG4:
23075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupMPEG4EncoderParameters(msg);
23085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
23095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingH263:
23115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupH263EncoderParameters(msg);
23125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
23135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingAVC:
23155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupAVCEncoderParameters(msg);
23165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
23175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2318c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        case OMX_VIDEO_CodingHEVC:
2319c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            err = setupHEVCEncoderParameters(msg);
2320c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            break;
2321c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
232289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP8:
232389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP9:
232489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            err = setupVPXEncoderParameters(msg);
232589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            break;
232689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
23275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
23285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
23295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGI("setupVideoEncoder succeeded");
23325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
23345778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
23355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23360dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dongstatus_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) {
23370dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    OMX_VIDEO_PARAM_INTRAREFRESHTYPE params;
23380dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    InitOMXParams(&params);
23390dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.nPortIndex = kPortIndexOutput;
23400dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
23410dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode);
23420dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
23430dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic ||
23440dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
23450dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
23460dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) {
23470dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
23480dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
23490dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nCirMBs = mbs;
23500dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
23510dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
23520dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive ||
23530dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
23540dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
23550dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) {
23560dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
23570dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
23580dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirMBs = mbs;
23590dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
23600dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t ref;
23610dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) {
23620dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
23630dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
23640dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirRef = ref;
23650dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
23660dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
23670dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = mOMX->setParameter(
23680dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            mNode, OMX_IndexParamVideoIntraRefresh,
23690dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            &params, sizeof(params));
23700dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    return err;
23710dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong}
23720dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
23735778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
23745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (iFramesInterval < 0) {
23755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0xFFFFFFFF;
23765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (iFramesInterval == 0) {
23775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0;
23785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_U32 ret = frameRate * iFramesInterval;
23805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return ret;
23815778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
23825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
238396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatic OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) {
238496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    int32_t tmp;
238596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    if (!msg->findInt32("bitrate-mode", &tmp)) {
238696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        return OMX_Video_ControlRateVariable;
238796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    }
238896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
238996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp);
239096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber}
239196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
23925778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
23935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
23945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
23955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
23965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
23975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
239996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
240096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
24015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
24025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
24035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
24045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
24055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
24065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
24075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
24085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
24115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&mpeg4type);
24125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPortIndex = kPortIndexOutput;
24135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
24155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
24165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
24185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
24195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nSliceHeaderSpacing = 0;
24225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bSVH = OMX_FALSE;
24235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bGov = OMX_FALSE;
24245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nAllowedPictureTypes =
24265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
24275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
24295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mpeg4type.nPFrames == 0) {
24305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
24315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nBFrames = 0;
24335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nIDCVLCThreshold = 0;
24345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bACPred = OMX_TRUE;
24355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nMaxPacketSize = 256;
24365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nTimeIncRes = 1000;
24375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nHeaderExtension = 0;
24385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bReversibleVLC = OMX_FALSE;
24395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
24415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
24425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
24435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
24445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
24455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
24465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
24485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
24505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
24515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
24525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
24545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
24555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
24585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
24595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
24615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
24625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
246496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
24655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
24675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
24685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
24715778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
24725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24735778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
24745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
24755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
24765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
24775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
24785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
248096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
248196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
24825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
24835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
24845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
24855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
24865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
24875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
24885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
24895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_H263TYPE h263type;
24925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h263type);
24935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPortIndex = kPortIndexOutput;
24945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
24965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
24975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
24995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
25005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nAllowedPictureTypes =
25035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
25045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
25065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h263type.nPFrames == 0) {
25075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
25085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nBFrames = 0;
25105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
25125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
25135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
25145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
25155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
25165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
25175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
25195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
25215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
25225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
25235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
25255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
25265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bPLUSPTYPEAllowed = OMX_FALSE;
25295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bForceRoundingTypeToZero = OMX_FALSE;
25305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPictureHeaderRepetition = 0;
25315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nGOBHeaderInterval = 0;
25325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
25345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
25355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
25375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
25385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
254096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
25415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
25435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
25445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
25475778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
25485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2549a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar// static
2550a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnarint /* OMX_VIDEO_AVCLEVELTYPE */ ACodec::getAVCLevelFor(
2551a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        int width, int height, int rate, int bitrate,
2552a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        OMX_VIDEO_AVCPROFILETYPE profile) {
2553a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    // convert bitrate to main/baseline profile kbps equivalent
2554a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    switch (profile) {
2555a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        case OMX_VIDEO_AVCProfileHigh10:
2556a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 3000); break;
2557a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        case OMX_VIDEO_AVCProfileHigh:
2558a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 1250); break;
2559a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        default:
2560a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 1000); break;
2561a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    }
2562a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
2563a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    // convert size and rate to MBs
2564a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    width = divUp(width, 16);
2565a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    height = divUp(height, 16);
2566a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    int mbs = width * height;
2567a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    rate *= mbs;
2568a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    int maxDimension = max(width, height);
2569a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
2570a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    static const int limits[][5] = {
2571a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        /*   MBps     MB   dim  bitrate        level */
2572a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    1485,    99,  28,     64, OMX_VIDEO_AVCLevel1  },
2573a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    1485,    99,  28,    128, OMX_VIDEO_AVCLevel1b },
2574a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    3000,   396,  56,    192, OMX_VIDEO_AVCLevel11 },
2575a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    6000,   396,  56,    384, OMX_VIDEO_AVCLevel12 },
2576a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   11880,   396,  56,    768, OMX_VIDEO_AVCLevel13 },
2577a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   11880,   396,  56,   2000, OMX_VIDEO_AVCLevel2  },
2578a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   19800,   792,  79,   4000, OMX_VIDEO_AVCLevel21 },
2579a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   20250,  1620, 113,   4000, OMX_VIDEO_AVCLevel22 },
2580a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   40500,  1620, 113,  10000, OMX_VIDEO_AVCLevel3  },
2581a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  108000,  3600, 169,  14000, OMX_VIDEO_AVCLevel31 },
2582a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  216000,  5120, 202,  20000, OMX_VIDEO_AVCLevel32 },
2583a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  245760,  8192, 256,  20000, OMX_VIDEO_AVCLevel4  },
2584a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  245760,  8192, 256,  50000, OMX_VIDEO_AVCLevel41 },
2585a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  522240,  8704, 263,  50000, OMX_VIDEO_AVCLevel42 },
2586a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  589824, 22080, 420, 135000, OMX_VIDEO_AVCLevel5  },
2587a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  983040, 36864, 543, 240000, OMX_VIDEO_AVCLevel51 },
2588a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        { 2073600, 36864, 543, 240000, OMX_VIDEO_AVCLevel52 },
2589a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    };
2590a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
2591a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    for (size_t i = 0; i < ARRAY_SIZE(limits); i++) {
2592a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        const int (&limit)[5] = limits[i];
2593a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        if (rate <= limit[0] && mbs <= limit[1] && maxDimension <= limit[2]
2594a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar                && bitrate <= limit[3]) {
2595a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            return limit[4];
2596a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        }
2597a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    }
2598a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    return 0;
2599a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar}
2600a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
26015778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
26025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
26035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
26045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
26055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
26065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
260896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
260996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
26105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
26115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
26125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
26135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
26145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
26155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
26165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
26175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26190dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = OK;
26200dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    int32_t intraRefreshMode = 0;
26210dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) {
26220dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode);
26230dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (err != OK) {
26240dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
26250dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong                    err, intraRefreshMode);
26260dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return err;
26270dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
26280dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
26290dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
26305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_AVCTYPE h264type;
26315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h264type);
26325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nPortIndex = kPortIndexOutput;
26335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26340dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    err = mOMX->getParameter(
26355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
26365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
26385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
26395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nAllowedPictureTypes =
26425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
26435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
26455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
26465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
26475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
26485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
26495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
26505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
26525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
26545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
26555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
26565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
26585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
26595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // XXX
26627c25df82dfc8bbedb58608242f0d923a4594bb14James Dong    if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) {
26637c25df82dfc8bbedb58608242f0d923a4594bb14James Dong        ALOGW("Use baseline profile instead of %d for AVC recording",
26647c25df82dfc8bbedb58608242f0d923a4594bb14James Dong            h264type.eProfile);
26655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
26665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
26695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nSliceHeaderSpacing = 0;
26705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bUseHadamard = OMX_TRUE;
26715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefFrames = 1;
26725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nBFrames = 0;
26735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
26745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (h264type.nPFrames == 0) {
26755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
26765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
26775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx10ActiveMinus1 = 0;
26785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx11ActiveMinus1 = 0;
26795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bEntropyCodingCABAC = OMX_FALSE;
26805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bWeightedPPrediction = OMX_FALSE;
26815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bconstIpred = OMX_FALSE;
26825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirect8x8Inference = OMX_FALSE;
26835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirectSpatialTemporal = OMX_FALSE;
26845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nCabacInitIdc = 0;
26855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.nBFrames != 0) {
26885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
26895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableUEP = OMX_FALSE;
26925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableFMO = OMX_FALSE;
26935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableASO = OMX_FALSE;
26945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableRS = OMX_FALSE;
26955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bFrameMBsOnly = OMX_TRUE;
26965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bMBAFF = OMX_FALSE;
26975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
26985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
27005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
27015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
27035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
27045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
270696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return configureBitrate(bitrate, bitrateMode);
27075778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
27085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2709c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachadstatus_t ACodec::setupHEVCEncoderParameters(const sp<AMessage> &msg) {
2710c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    int32_t bitrate, iFrameInterval;
2711c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findInt32("bitrate", &bitrate)
2712c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
2713c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return INVALID_OPERATION;
2714c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2715c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2716c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
2717c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2718c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    float frameRate;
2719c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findFloat("frame-rate", &frameRate)) {
2720c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t tmp;
2721c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("frame-rate", &tmp)) {
2722c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
2723c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
2724c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        frameRate = (float)tmp;
2725c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2726c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2727c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_PARAM_HEVCTYPE hevcType;
2728c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    InitOMXParams(&hevcType);
2729c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    hevcType.nPortIndex = kPortIndexOutput;
2730c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2731c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    status_t err = OK;
2732c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    err = mOMX->getParameter(
2733c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
2734c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
2735c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
2736c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2737c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2738c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    int32_t profile;
2739c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (msg->findInt32("profile", &profile)) {
2740c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t level;
2741c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("level", &level)) {
2742c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
2743c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
2744c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2745c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        err = verifySupportForProfileAndLevel(profile, level);
2746c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (err != OK) {
2747c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return err;
2748c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
2749c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2750c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eProfile = static_cast<OMX_VIDEO_HEVCPROFILETYPE>(profile);
2751c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eLevel = static_cast<OMX_VIDEO_HEVCLEVELTYPE>(level);
2752c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2753c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2754c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    // TODO: Need OMX structure definition for setting iFrameInterval
2755c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2756c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    err = mOMX->setParameter(
2757c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
2758c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
2759c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
2760c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2761c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2762c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    return configureBitrate(bitrate, bitrateMode);
2763c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad}
2764c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
276589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huberstatus_t ACodec::setupVPXEncoderParameters(const sp<AMessage> &msg) {
276689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    int32_t bitrate;
27674154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    int32_t iFrameInterval = 0;
27684154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    size_t tsLayers = 0;
27694154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE pattern =
27704154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        OMX_VIDEO_VPXTemporalLayerPatternNone;
27714154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    static const uint32_t kVp8LayerRateAlloction
27724154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS]
27734154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS] = {
27744154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        {100, 100, 100},  // 1 layer
27754154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 60, 100, 100},  // 2 layers {60%, 40%}
27764154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 40,  60, 100},  // 3 layers {40%, 20%, 40%}
27774154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    };
277889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    if (!msg->findInt32("bitrate", &bitrate)) {
277989b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        return INVALID_OPERATION;
278089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    }
27814154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    msg->findInt32("i-frame-interval", &iFrameInterval);
278289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
278389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
278489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
27854154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    float frameRate;
27864154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (!msg->findFloat("frame-rate", &frameRate)) {
27874154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        int32_t tmp;
27884154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (!msg->findInt32("frame-rate", &tmp)) {
27894154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            return INVALID_OPERATION;
27904154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
27914154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        frameRate = (float)tmp;
27924154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
27934154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
27944154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    AString tsSchema;
27954154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (msg->findString("ts-schema", &tsSchema)) {
27964154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (tsSchema == "webrtc.vp8.1-layer") {
27974154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
27984154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 1;
27994154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else if (tsSchema == "webrtc.vp8.2-layer") {
28004154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
28014154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 2;
28024154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else if (tsSchema == "webrtc.vp8.3-layer") {
28034154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
28044154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 3;
28054154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else {
28064154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            ALOGW("Unsupported ts-schema [%s]", tsSchema.c_str());
28074154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
28084154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
28094154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
28104154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
28114154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    InitOMXParams(&vp8type);
28124154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    vp8type.nPortIndex = kPortIndexOutput;
28134154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    status_t err = mOMX->getParameter(
28144154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
28154154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            &vp8type, sizeof(vp8type));
28164154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
28174154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (err == OK) {
28184154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (iFrameInterval > 0) {
28194154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nKeyFrameInterval = setPFramesSpacing(iFrameInterval, frameRate);
28204154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
28214154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.eTemporalPattern = pattern;
28224154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.nTemporalLayerCount = tsLayers;
28234154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (tsLayers > 0) {
28244154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            for (size_t i = 0; i < OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS; i++) {
28254154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                vp8type.nTemporalLayerBitrateRatio[i] =
28264154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                    kVp8LayerRateAlloction[tsLayers - 1][i];
28274154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            }
28284154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
28294154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (bitrateMode == OMX_Video_ControlRateConstant) {
28304154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMinQuantizer = 2;
28314154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMaxQuantizer = 63;
28324154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
28334154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
28344154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        err = mOMX->setParameter(
28354154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
28364154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                &vp8type, sizeof(vp8type));
28374154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (err != OK) {
28384154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            ALOGW("Extended VP8 parameters set failed: %d", err);
28394154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
28404154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
28414154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
284289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    return configureBitrate(bitrate, bitrateMode);
284389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber}
284489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
28455778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::verifySupportForProfileAndLevel(
28465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t profile, int32_t level) {
28475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
28485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&params);
28495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    params.nPortIndex = kPortIndexOutput;
28505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (params.nProfileIndex = 0;; ++params.nProfileIndex) {
28525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
28535778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode,
28545778822d86b0337407514b9372562b86edfa91cdAndreas Huber                OMX_IndexParamVideoProfileLevelQuerySupported,
28555778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &params,
28565778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sizeof(params));
28575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
28595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
28605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
28615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
28635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
28645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (profile == supportedProfile && level <= supportedLevel) {
28665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OK;
28675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
28685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28695778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
28705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
287196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatus_t ACodec::configureBitrate(
287296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) {
28735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
28745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&bitrateType);
28755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
28765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
28785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
28795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
28805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
28825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
28835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
288596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    bitrateType.eControlRate = bitrateMode;
28865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nTargetBitrate = bitrate;
28875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
28895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
28905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
28915778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
28925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28935778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupErrorCorrectionParameters() {
28945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
28955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&errorCorrectionType);
28965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nPortIndex = kPortIndexOutput;
28975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
28995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
29005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
29015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
29035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OK;  // Optional feature. Ignore this failure
29045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableHEC = OMX_FALSE;
29075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableResync = OMX_TRUE;
29085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nResynchMarkerSpacing = 256;
29095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
29105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableRVLC = OMX_FALSE;
29115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
29135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
29145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
29155778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
29165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2917f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoFormatOnPort(
2918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
2919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat) {
2920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
2921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
2922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
2923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
2925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
2927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
2930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
2932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // XXX Need a (much) better heuristic to compute input buffer sizes.
2933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const size_t X = 64 * 1024;
2934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (def.nBufferSize < X) {
2935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.nBufferSize = X;
2936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
2940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameWidth = width;
2942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameHeight = height;
2943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
2945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eCompressionFormat = compressionFormat;
2946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eColorFormat = OMX_COLOR_FormatUnused;
2947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
2950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
2953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2955f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::initNativeWindow() {
2956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL) {
2957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
2958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
2961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2964d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Hubersize_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
2965d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    size_t n = 0;
2966d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2967d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2968d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        const BufferInfo &info = mBuffers[portIndex].itemAt(i);
2969d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2970d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
2971d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            ++n;
2972d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        }
2973d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    }
2974d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2975d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    return n;
2976d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber}
2977d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
29787e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubersize_t ACodec::countBuffersOwnedByNativeWindow() const {
29797e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    size_t n = 0;
29807e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
29817e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
29827e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
29837e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
29847e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
29857e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            ++n;
29867e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        }
29877e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
29887e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
29897e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    return n;
29907e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
29917e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
29927e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubervoid ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
29937e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (mNativeWindow == NULL) {
29947e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        return;
29957e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
29967e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
2997e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    while (countBuffersOwnedByNativeWindow() > mNumUndequeuedBuffers
29987e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            && dequeueBufferFromNativeWindow() != NULL) {
2999c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        // these buffers will be submitted as regular buffers; account for this
3000c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        if (mStoreMetaDataInOutputBuffers && mMetaDataBuffersToSubmit > 0) {
3001c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar            --mMetaDataBuffersToSubmit;
3002c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        }
30037e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
30047e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
30057e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
3006f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs(
3007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
3008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
3009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
3010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus != BufferInfo::OWNED_BY_US
3012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3013609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGV("[%s] Buffer %u on port %u still has status %d",
3014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mComponentName.c_str(),
3015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info->mBufferID, portIndex, info->mStatus);
3016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
3017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3023f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs() {
3024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return allYourBuffersAreBelongToUs(kPortIndexInput)
3025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        && allYourBuffersAreBelongToUs(kPortIndexOutput);
3026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3028f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::deferMessage(const sp<AMessage> &msg) {
3029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool wasEmptyBefore = mDeferredQueue.empty();
3030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.push_back(msg);
3031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3033f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::processDeferredMessages() {
3034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> > queue = mDeferredQueue;
3035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.clear();
3036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> >::iterator it = queue.begin();
3038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while (it != queue.end()) {
3039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        onMessageReceived(*it++);
3040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
304303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar// static
3044229d242665c612fd97431d1e7ac004823b47f181Lajos Molnarbool ACodec::describeDefaultColorFormat(DescribeColorFormatParams &params) {
304503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    MediaImage &image = params.sMediaImage;
304603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    memset(&image, 0, sizeof(image));
304703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
304803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mType = MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
304903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mNumPlanes = 0;
305003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
305103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    const OMX_COLOR_FORMATTYPE fmt = params.eColorFormat;
305203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mWidth = params.nFrameWidth;
305303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mHeight = params.nFrameHeight;
305403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
305503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    // only supporting YUV420
305603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    if (fmt != OMX_COLOR_FormatYUV420Planar &&
305703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        fmt != OMX_COLOR_FormatYUV420PackedPlanar &&
305803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        fmt != OMX_COLOR_FormatYUV420SemiPlanar &&
305903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        fmt != OMX_COLOR_FormatYUV420PackedSemiPlanar) {
306003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        ALOGW("do not know color format 0x%x = %d", fmt, fmt);
3061229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return false;
306203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    }
306303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
3064b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    // TEMPORARY FIX for some vendors that advertise sliceHeight as 0
3065b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    if (params.nStride != 0 && params.nSliceHeight == 0) {
3066b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        ALOGW("using sliceHeight=%u instead of what codec advertised (=0)",
3067b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar                params.nFrameHeight);
3068b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        params.nSliceHeight = params.nFrameHeight;
3069b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    }
3070b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar
3071b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    // we need stride and slice-height to be non-zero
3072b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    if (params.nStride == 0 || params.nSliceHeight == 0) {
3073b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        ALOGW("cannot describe color format 0x%x = %d with stride=%u and sliceHeight=%u",
3074b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar                fmt, fmt, params.nStride, params.nSliceHeight);
3075b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        return false;
3076b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    }
3077b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar
307803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    // set-up YUV format
307903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mType = MediaImage::MEDIA_IMAGE_TYPE_YUV;
308003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mNumPlanes = 3;
308103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mBitDepth = 8;
308203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mOffset = 0;
308303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mColInc = 1;
308403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mRowInc = params.nStride;
308503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mHorizSubsampling = 1;
308603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mVertSubsampling = 1;
308703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
308803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    switch (fmt) {
308903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420Planar: // used for YV12
309003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420PackedPlanar:
309103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight;
309203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mColInc = 1;
309303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mRowInc = params.nStride / 2;
309403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mHorizSubsampling = 2;
309503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mVertSubsampling = 2;
309603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
309703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset
309803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    + (params.nStride * params.nSliceHeight / 4);
309903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mColInc = 1;
310003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mRowInc = params.nStride / 2;
310103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mHorizSubsampling = 2;
310203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mVertSubsampling = 2;
310303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            break;
310403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
310503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420SemiPlanar:
310603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            // FIXME: NV21 for sw-encoder, NV12 for decoder and hw-encoder
310703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420PackedSemiPlanar:
310803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            // NV12
310903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight;
311003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mColInc = 2;
311103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mRowInc = params.nStride;
311203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mHorizSubsampling = 2;
311303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mVertSubsampling = 2;
311403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
311503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset + 1;
311603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mColInc = 2;
311703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mRowInc = params.nStride;
311803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mHorizSubsampling = 2;
311903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mVertSubsampling = 2;
312003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            break;
312103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
312203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        default:
312303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            TRESPASS();
312403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    }
3125229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    return true;
3126229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar}
3127229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3128229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar// static
3129229d242665c612fd97431d1e7ac004823b47f181Lajos Molnarbool ACodec::describeColorFormat(
3130229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        const sp<IOMX> &omx, IOMX::node_id node,
3131229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        DescribeColorFormatParams &describeParams)
3132229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar{
3133229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    OMX_INDEXTYPE describeColorFormatIndex;
3134229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    if (omx->getExtensionIndex(
3135229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            node, "OMX.google.android.index.describeColorFormat",
3136229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            &describeColorFormatIndex) != OK ||
3137229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        omx->getParameter(
3138229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            node, describeColorFormatIndex,
3139229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            &describeParams, sizeof(describeParams)) != OK) {
3140229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return describeDefaultColorFormat(describeParams);
3141229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    }
3142229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    return describeParams.sMediaImage.mType !=
3143229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
3144229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar}
3145229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3146229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar// static
3147229d242665c612fd97431d1e7ac004823b47f181Lajos Molnarbool ACodec::isFlexibleColorFormat(
3148229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar         const sp<IOMX> &omx, IOMX::node_id node,
3149229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar         uint32_t colorFormat, OMX_U32 *flexibleEquivalent) {
3150229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    DescribeColorFormatParams describeParams;
3151229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    InitOMXParams(&describeParams);
3152229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.eColorFormat = (OMX_COLOR_FORMATTYPE)colorFormat;
3153229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    // reasonable dummy values
3154229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nFrameWidth = 128;
3155229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nFrameHeight = 128;
3156229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nStride = 128;
3157229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nSliceHeight = 128;
3158229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3159229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    CHECK(flexibleEquivalent != NULL);
3160229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3161229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    if (!describeColorFormat(omx, node, describeParams)) {
3162229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return false;
3163229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    }
3164229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3165229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    const MediaImage &img = describeParams.sMediaImage;
3166229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    if (img.mType == MediaImage::MEDIA_IMAGE_TYPE_YUV) {
3167229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        if (img.mNumPlanes != 3 ||
3168229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            img.mPlane[img.Y].mHorizSubsampling != 1 ||
3169229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            img.mPlane[img.Y].mVertSubsampling != 1) {
3170229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            return false;
3171229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
3172229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3173229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        // YUV 420
3174229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        if (img.mPlane[img.U].mHorizSubsampling == 2
3175229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.U].mVertSubsampling == 2
3176229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.V].mHorizSubsampling == 2
3177229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.V].mVertSubsampling == 2) {
3178229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            // possible flexible YUV420 format
3179229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            if (img.mBitDepth <= 8) {
3180229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar               *flexibleEquivalent = OMX_COLOR_FormatYUV420Flexible;
3181229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar               return true;
3182229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            }
3183229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
3184229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    }
3185229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    return false;
318603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar}
318703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
3188e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarstatus_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> &notify) {
3189e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    // TODO: catch errors an return them instead of using CHECK
319031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
319131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    InitOMXParams(&def);
3192e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    def.nPortIndex = portIndex;
319331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
319431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ(mOMX->getParameter(
319531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)),
319631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber             (status_t)OK);
319731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3198e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ((int)def.eDir,
3199e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            (int)(portIndex == kPortIndexOutput ? OMX_DirOutput : OMX_DirInput));
320031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
320131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    switch (def.eDomain) {
320231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainVideo:
320331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
320431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
3205e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            switch ((int)videoDef->eCompressionFormat) {
3206e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_VIDEO_CodingUnused:
3207e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3208e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(mIsEncoder ^ (portIndex == kPortIndexOutput));
3209e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
3210e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3211e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("stride", videoDef->nStride);
3212e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("slice-height", videoDef->nSliceHeight);
3213e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("color-format", videoDef->eColorFormat);
3214e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
321503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    DescribeColorFormatParams describeParams;
321603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    InitOMXParams(&describeParams);
321703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    describeParams.eColorFormat = videoDef->eColorFormat;
321803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    describeParams.nFrameWidth = videoDef->nFrameWidth;
321903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    describeParams.nFrameHeight = videoDef->nFrameHeight;
322003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    describeParams.nStride = videoDef->nStride;
322103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    describeParams.nSliceHeight = videoDef->nSliceHeight;
322203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
3223229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                    if (describeColorFormat(mOMX, mNode, describeParams)) {
322403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                        notify->setBuffer(
322503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                                "image-data",
322603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                                ABuffer::CreateAsCopy(
322703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                                        &describeParams.sMediaImage,
322803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                                        sizeof(describeParams.sMediaImage)));
322903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    }
323003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
323191a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                    if (portIndex != kPortIndexOutput) {
323291a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                        // TODO: also get input crop
323391a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                        break;
323491a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                    }
323591a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar
3236e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_CONFIG_RECTTYPE rect;
3237e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&rect);
323891a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                    rect.nPortIndex = portIndex;
3239e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3240e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    if (mOMX->getConfig(
324191a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                mNode,
324291a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                (portIndex == kPortIndexOutput ?
324391a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                        OMX_IndexConfigCommonOutputCrop :
324491a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                        OMX_IndexConfigCommonInputCrop),
3245e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &rect, sizeof(rect)) != OK) {
3246e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nLeft = 0;
3247e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nTop = 0;
3248e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nWidth = videoDef->nFrameWidth;
3249e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nHeight = videoDef->nFrameHeight;
3250e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    }
325131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3252e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nLeft, 0);
3253e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nTop, 0);
3254e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nWidth, 0u);
3255e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nHeight, 0u);
3256e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_LE(rect.nLeft + rect.nWidth - 1, videoDef->nFrameWidth);
3257e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_LE(rect.nTop + rect.nHeight - 1, videoDef->nFrameHeight);
3258e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3259e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setRect(
3260577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            "crop",
3261577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nLeft,
3262577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nTop,
3263e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                            rect.nLeft + rect.nWidth - 1,
3264e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                            rect.nTop + rect.nHeight - 1);
3265e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3266e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3267e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
32684730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
32694730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP8:
32704730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP9:
32714730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                {
32724730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
32734730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    InitOMXParams(&vp8type);
32744730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    vp8type.nPortIndex = kPortIndexOutput;
32754730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    status_t err = mOMX->getParameter(
32764730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            mNode,
32774730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
32784730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            &vp8type,
32794730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            sizeof(vp8type));
32804730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
32814730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    if (err == OK) {
32824730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        AString tsSchema = "none";
32834730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        if (vp8type.eTemporalPattern
32844730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                == OMX_VIDEO_VPXTemporalLayerPatternWebRTC) {
32854730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            switch (vp8type.nTemporalLayerCount) {
32864730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 1:
32874730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
32884730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.1-layer";
32894730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
32904730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
32914730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 2:
32924730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
32934730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.2-layer";
32944730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
32954730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
32964730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 3:
32974730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
32984730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.3-layer";
32994730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
33004730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
33014730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                default:
33024730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
33034730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
33044730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
33054730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            }
33064730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        }
33074730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        notify->setString("ts-schema", tsSchema);
33084730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    }
33094730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    // Fall through to set up mime.
33104730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                }
33114730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
3312e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                default:
3313e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3314e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(mIsEncoder ^ (portIndex == kPortIndexInput));
3315e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    AString mime;
3316e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    if (GetMimeTypeForVideoCoding(
3317e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        videoDef->eCompressionFormat, &mime) != OK) {
3318e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", "application/octet-stream");
3319e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    } else {
3320e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", mime.c_str());
3321e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    }
3322e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3323e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
332431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            }
3325e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3326e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("width", videoDef->nFrameWidth);
3327e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("height", videoDef->nFrameHeight);
332831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
332931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
333031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
333131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainAudio:
333231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
333331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
333431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
333597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            switch ((int)audioDef->eEncoding) {
3336e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingPCM:
3337e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3338e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_PCMMODETYPE params;
3339e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3340e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3341e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3342e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3343e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioPcm,
3344e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3345e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3346e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
334714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_GT(params.nChannels, 0);
3348e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK(params.nChannels == 1 || params.bInterleaved);
3349e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(params.nBitPerSample, 16u);
335014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
335114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.eNumData,
335214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_NumericalDataSigned);
335314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
335414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.ePCMMode,
335514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_AUDIO_PCMModeLinear);
3356e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3357e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
3358e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
3359e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSamplingRate);
3360e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3361e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mChannelMaskPresent) {
3362e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("channel-mask", mChannelMask);
33638b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                    }
3364e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
33658b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                }
33669806555d3930be43e11106281dee354820ac1c88Andreas Huber
3367e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAAC:
3368e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3369e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AACPROFILETYPE params;
3370e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3371e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3372e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3373e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3374e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAac,
3375e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3376e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3377e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3378e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
3379e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
3380e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
3381e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
3382e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
3383e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3384e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAMR:
3385e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3386e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AMRTYPE params;
3387e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3388e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
33899806555d3930be43e11106281dee354820ac1c88Andreas Huber
3390e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3391e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAmr,
3392e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3393e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3394e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3395e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", 1);
3396e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) {
3397e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
3398e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_WB);
3399e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3400e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 16000);
3401e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    } else {
3402e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
3403e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
3404e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3405e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 8000);
3406e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
3407e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
3408e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
3409e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3410e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingFLAC:
3411e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3412e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_FLACTYPE params;
3413e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3414e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3415e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3416e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3417e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioFlac,
3418e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3419e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3420e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3421e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC);
3422e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
3423e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
3424e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
3425e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
3426e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3427e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingMP3:
3428e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3429e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_MP3TYPE params;
3430e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
3431e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3432e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3433e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_EQ(mOMX->getParameter(
3434e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                mNode, OMX_IndexParamAudioMp3,
3435e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &params, sizeof(params)),
3436e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                             (status_t)OK);
3437e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3438e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MPEG);
3439e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
3440e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
3441e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3442e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
3443e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3444e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingVORBIS:
3445e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3446e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_VORBISTYPE params;
3447e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
3448e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3449e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3450e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_EQ(mOMX->getParameter(
3451e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                mNode, OMX_IndexParamAudioVorbis,
3452e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &params, sizeof(params)),
3453e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                             (status_t)OK);
3454e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3455e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_VORBIS);
3456e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
3457e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
3458e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3459e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
3460e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
346197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                case OMX_AUDIO_CodingAndroidAC3:
346297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                {
346397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    OMX_AUDIO_PARAM_ANDROID_AC3TYPE params;
346497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    InitOMXParams(&params);
3465e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
346697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
346797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    CHECK_EQ((status_t)OK, mOMX->getParameter(
346897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            mNode,
346997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
347097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            &params,
347197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            sizeof(params)));
347297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
347397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AC3);
347497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("channel-count", params.nChannels);
347597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("sample-rate", params.nSampleRate);
347697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    break;
347797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                }
3478e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
34798c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                case OMX_AUDIO_CodingAndroidOPUS:
34808c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                {
34818c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    OMX_AUDIO_PARAM_ANDROID_OPUSTYPE params;
34828c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    InitOMXParams(&params);
34838c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    params.nPortIndex = portIndex;
34848c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
34858c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    CHECK_EQ((status_t)OK, mOMX->getParameter(
34868c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            mNode,
34878c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus,
34888c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            &params,
34898c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            sizeof(params)));
34908c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
34918c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_OPUS);
34928c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("channel-count", params.nChannels);
34938c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("sample-rate", params.nSampleRate);
34948c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    break;
34958c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                }
34968c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
349710d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                case OMX_AUDIO_CodingG711:
349810d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                {
349910d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    OMX_AUDIO_PARAM_PCMMODETYPE params;
350010d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    InitOMXParams(&params);
350110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    params.nPortIndex = portIndex;
350210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
350310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    CHECK_EQ((status_t)OK, mOMX->getParameter(
350410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                            mNode,
350510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                            (OMX_INDEXTYPE)OMX_IndexParamAudioPcm,
350610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                            &params,
350710d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                            sizeof(params)));
350810d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
350910d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    const char *mime = NULL;
351010d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    if (params.ePCMMode == OMX_AUDIO_PCMModeMULaw) {
351110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_G711_MLAW;
351210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    } else if (params.ePCMMode == OMX_AUDIO_PCMModeALaw) {
351310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_G711_ALAW;
351410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    } else { // params.ePCMMode == OMX_AUDIO_PCMModeLinear
351510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_RAW;
351610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    }
351710d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setString("mime", mime);
351810d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setInt32("channel-count", params.nChannels);
351910d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setInt32("sample-rate", params.nSamplingRate);
352010d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    break;
352110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                }
352210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
3523e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                default:
3524e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    ALOGE("UNKNOWN AUDIO CODING: %d\n", audioDef->eEncoding);
3525e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    TRESPASS();
3526e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
352731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
352831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
352931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
353031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        default:
353131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            TRESPASS();
353231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    }
353331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3534e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    return OK;
3535e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar}
3536e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3537e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarvoid ACodec::sendFormatChange(const sp<AMessage> &reply) {
35384e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    sp<AMessage> notify = mBaseOutputFormat->dup();
3539e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    notify->setInt32("what", kWhatOutputFormatChanged);
3540e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3541e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ(getPortFormat(kPortIndexOutput, notify), (status_t)OK);
3542e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3543e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    AString mime;
3544e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK(notify->findString("mime", &mime));
3545e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3546e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    int32_t left, top, right, bottom;
3547e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if (mime == MEDIA_MIMETYPE_VIDEO_RAW &&
3548e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        mNativeWindow != NULL &&
3549e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->findRect("crop", &left, &top, &right, &bottom)) {
3550e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        // notify renderer of the crop change
3551e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        // NOTE: native window uses extended right-bottom coordinate
3552e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        reply->setRect("crop", left, top, right + 1, bottom + 1);
3553e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    } else if (mime == MEDIA_MIMETYPE_AUDIO_RAW &&
3554e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar               (mEncoderDelay || mEncoderPadding)) {
3555e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        int32_t channelCount;
3556e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        CHECK(notify->findInt32("channel-count", &channelCount));
3557e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        size_t frameSize = channelCount * sizeof(int16_t);
3558e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        if (mSkipCutBuffer != NULL) {
3559e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            size_t prevbufsize = mSkipCutBuffer->size();
3560e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            if (prevbufsize != 0) {
3561e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                ALOGW("Replacing SkipCutBuffer holding %d "
3562e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                      "bytes",
3563e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                      prevbufsize);
3564e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            }
3565e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        }
3566e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        mSkipCutBuffer = new SkipCutBuffer(
3567e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                mEncoderDelay * frameSize,
3568e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                mEncoderPadding * frameSize);
3569e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
3570e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
357131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->post();
357231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
357331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mSentFormat = true;
357431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber}
357531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
35765778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
3577cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    sp<AMessage> notify = mNotify->dup();
3578d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatError);
3579251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    ALOGE("signalError(omxError %#x, internalError %d)", error, internalError);
3580251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
3581251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (internalError == UNKNOWN_ERROR) { // find better error code
3582251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        const status_t omxStatus = statusFromOMXError(error);
3583251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        if (omxStatus != 0) {
3584251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            internalError = omxStatus;
3585251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        } else {
3586251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            ALOGW("Invalid OMX error %#x", error);
3587251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        }
3588251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
35895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("err", internalError);
3590251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    notify->setInt32("actionCode", ACTION_CODE_FATAL); // could translate from OMX error.
3591cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->post();
3592cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber}
3593cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber
3594bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huberstatus_t ACodec::pushBlankBuffersToNativeWindow() {
3595bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    status_t err = NO_ERROR;
3596bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    ANativeWindowBuffer* anb = NULL;
3597bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int numBufs = 0;
3598bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int minUndequeuedBufs = 0;
3599bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3600bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We need to reconnect to the ANativeWindow as a CPU client to ensure that
3601bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // no frames get dropped by SurfaceFlinger assuming that these are video
3602bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // frames.
3603bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_disconnect(mNativeWindow.get(),
3604bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_MEDIA);
3605bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3606bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
3607bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3608bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
3609bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3610bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3611bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_connect(mNativeWindow.get(),
3612bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_CPU);
3613bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3614bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
3615bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3616bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
3617bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3618bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3619bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffers_geometry(mNativeWindow.get(), 1, 1,
3620bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            HAL_PIXEL_FORMAT_RGBX_8888);
3621bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3622bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffers_geometry failed: %s (%d)",
3623bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3624bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
3625bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3626bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
362787eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin    err = native_window_set_scaling_mode(mNativeWindow.get(),
362887eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
362987eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin    if (err != NO_ERROR) {
363087eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin        ALOGE("error pushing blank_frames: set_scaling_mode failed: %s (%d)",
363187eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin              strerror(-err), -err);
363287eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin        goto error;
3633bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3634bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3635bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_usage(mNativeWindow.get(),
3636bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            GRALLOC_USAGE_SW_WRITE_OFTEN);
3637bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3638bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_usage failed: %s (%d)",
3639bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3640bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
3641bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3642bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3643bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = mNativeWindow->query(mNativeWindow.get(),
3644bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs);
3645bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3646bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: MIN_UNDEQUEUED_BUFFERS query "
3647bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                "failed: %s (%d)", strerror(-err), -err);
3648bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
3649bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3650bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3651bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    numBufs = minUndequeuedBufs + 1;
3652bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffer_count(mNativeWindow.get(), numBufs);
3653bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3654bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffer_count failed: %s (%d)",
3655bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3656bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
3657bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3658bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3659bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We  push numBufs + 1 buffers to ensure that we've drawn into the same
3660bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // buffer twice.  This should guarantee that the buffer has been displayed
3661bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // on the screen and then been replaced, so an previous video frames are
3662bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // guaranteed NOT to be currently displayed.
3663bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    for (int i = 0; i < numBufs + 1; i++) {
36641e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        int fenceFd = -1;
36651e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &anb);
3666bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3667bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: dequeueBuffer failed: %s (%d)",
3668bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3669bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
3670bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3671bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3672bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
3673bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3674bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Fill the buffer with the a 1x1 checkerboard pattern ;)
3675bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        uint32_t* img = NULL;
3676bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
3677bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3678bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: lock failed: %s (%d)",
3679bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3680bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
3681bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3682bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3683bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        *img = 0;
3684bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3685bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->unlock();
3686bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3687bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: unlock failed: %s (%d)",
3688bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3689bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
3690bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3691bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3692bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->queueBuffer(mNativeWindow.get(),
36931e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                buf->getNativeBuffer(), -1);
3694bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3695bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: queueBuffer failed: %s (%d)",
3696bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3697bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
3698bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3699bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3700bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        anb = NULL;
3701bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3702bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3703bc098410be55f9d96f394b3981a0c482b83859b6Andreas Hubererror:
3704bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3705bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3706bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after an error.
3707bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (anb != NULL) {
37081e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis            mNativeWindow->cancelBuffer(mNativeWindow.get(), anb, -1);
3709bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3710bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3711bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_disconnect(mNativeWindow.get(),
3712bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
3713bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_connect(mNativeWindow.get(),
3714bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
3715bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3716bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
3717bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    } else {
3718bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after success.
3719bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_disconnect(mNativeWindow.get(),
3720bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
3721bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3722bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
3723bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3724bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
3725bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3726bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3727bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_connect(mNativeWindow.get(),
3728bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
3729bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3730bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
3731bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3732bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
3733bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3734bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3735bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return NO_ERROR;
3736bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3737bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber}
3738bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3741eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberACodec::PortDescription::PortDescription() {
3742eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3743eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3744496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t ACodec::requestIDRFrame() {
3745496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    if (!mIsEncoder) {
3746496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        return ERROR_UNSUPPORTED;
3747496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    }
3748496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
3749496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    OMX_CONFIG_INTRAREFRESHVOPTYPE params;
3750496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    InitOMXParams(&params);
3751496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
3752496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.nPortIndex = kPortIndexOutput;
3753496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.IntraRefreshVOP = OMX_TRUE;
3754496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
3755496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    return mOMX->setConfig(
3756496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            mNode,
3757496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            OMX_IndexConfigVideoIntraVOPRefresh,
3758496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            &params,
3759496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            sizeof(params));
3760496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
3761496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
3762eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubervoid ACodec::PortDescription::addBuffer(
3763eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        IOMX::buffer_id id, const sp<ABuffer> &buffer) {
3764eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBufferIDs.push_back(id);
3765eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBuffers.push_back(buffer);
3766eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3767eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3768eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersize_t ACodec::PortDescription::countBuffers() {
3769eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.size();
3770eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3771eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3772eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberIOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const {
3773eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.itemAt(index);
3774eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3775eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3776eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const {
3777eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBuffers.itemAt(index);
3778eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3779eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3780eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber////////////////////////////////////////////////////////////////////////////////
3781eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3782f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
3783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : AState(parentState),
3784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mCodec(codec) {
3785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3787ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas HuberACodec::BaseState::PortMode ACodec::BaseState::getPortMode(
3788ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
3789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return KEEP_BUFFERS;
3790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3792f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
3793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatInputBufferFilled:
3795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onInputBufferFilled(msg);
3797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatOutputBufferDrained:
3801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onOutputBufferDrained(msg);
3803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatOMXMessage:
3807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXMessage(msg);
3809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
38117cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
38127cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
38137cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
3814251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            // This may result in an app illegal state exception.
38157cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            ALOGE("Message 0x%x was not handled", msg->what());
38167cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
38177cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            return true;
38187cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
38197cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
3820ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        case ACodec::kWhatOMXDied:
3821ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        {
3822251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            // This will result in kFlagSawMediaServerDie handling in MediaCodec.
3823ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            ALOGE("OMX/mediaserver died, signalling error!");
3824ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT);
3825ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            break;
3826ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        }
3827ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
382830358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        case ACodec::kWhatReleaseCodecInstance:
382930358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        {
383030358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            ALOGI("[%s] forcing the release of codec",
383130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar                    mCodec->mComponentName.c_str());
383230358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            status_t err = mCodec->mOMX->freeNode(mCodec->mNode);
383330358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            ALOGE_IF("[%s] failed to release codec instance: err=%d",
383430358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar                       mCodec->mComponentName.c_str(), err);
383530358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            sp<AMessage> notify = mCodec->mNotify->dup();
383630358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
383730358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            notify->post();
383830358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            break;
383930358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        }
384030358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar
3841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
3843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3848f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
3849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t type;
3850f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findInt32("type", &type));
3851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
38525e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // there is a possibility that this is an outstanding message for a
38535e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // codec that we have already destroyed
38545e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    if (mCodec->mNode == NULL) {
38555e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar        ALOGI("ignoring message as already freed component: %s",
38565e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar                msg->debugString().c_str());
38575e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar        return true;
38585e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    }
38595e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar
3860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::node_id nodeID;
3861609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("node", (int32_t*)&nodeID));
3862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(nodeID, mCodec->mNode);
3863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (type) {
3865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EVENT:
3866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t event, data1, data2;
3868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("event", &event));
3869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data1", &data1));
3870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data2", &data2));
3871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
38720af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            if (event == OMX_EventCmdComplete
38730af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data1 == OMX_CommandFlush
38740af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data2 == (int32_t)OMX_ALL) {
38750af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // Use of this notification is not consistent across
38760af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // implementations. We'll drop this notification and rely
38770af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // on flush-complete notifications on the individual port
38780af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // indices instead.
38790af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
38800af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                return true;
38810af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            }
38820af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
3883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEvent(
3884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_EVENTTYPE>(event),
3885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data1),
3886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data2));
3887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EMPTY_BUFFER_DONE:
3890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
3892609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
3893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEmptyBufferDone(bufferID);
3895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::FILL_BUFFER_DONE:
3898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
3900609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
3901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t rangeOffset, rangeLength, flags;
3903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs;
3904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_offset", &rangeOffset));
3906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_length", &rangeLength));
3907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("flags", &flags));
3908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt64("timestamp", &timeUs));
3909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXFillBufferDone(
3911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    bufferID,
3912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (size_t)rangeOffset, (size_t)rangeLength,
3913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (OMX_U32)flags,
3914784e24e386b088c05d653ab482f2e95cb53e3d01Andy Hung                    timeUs);
3915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
3919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3923f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEvent(
3924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (event != OMX_EventError) {
39263856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] EVENT(%d, 0x%08lx, 0x%08lx)",
3927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mCodec->mComponentName.c_str(), event, data1, data2);
3928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return false;
3930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
393229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block    ALOGE("[%s] ERROR(0x%08lx)", mCodec->mComponentName.c_str(), data1);
3933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3934251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // verify OMX component sends back an error we expect.
3935251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    OMX_ERRORTYPE omxError = (OMX_ERRORTYPE)data1;
3936251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (!isOMXError(omxError)) {
3937251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        ALOGW("Invalid OMX error %#x", omxError);
3938251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        omxError = OMX_ErrorUndefined;
3939251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
3940251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    mCodec->signalError(omxError);
3941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3945f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID) {
39463856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] onOMXEmptyBufferDone %p",
3947349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber         mCodec->mComponentName.c_str(), bufferID);
3948349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexInput, bufferID);
3951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
3953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
395596e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // We're in "store-metadata-in-buffers" mode, the underlying
395696e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // OMX component had access to data that's implicitly refcounted
395796e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // by this "MediaBuffer" object. Now that the OMX component has
395896e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // told us that it's done with the input buffer, we can decrement
395996e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // the mediaBuffer's reference count.
396096e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    info->mData->setMediaBufferBase(NULL);
3961d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
3963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            postFillThisBuffer(info);
3970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();  // Not currently used
3976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3983f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
3984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
3985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
3989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
3991d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatFillThisBuffer);
3992609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    notify->setInt32("buffer-id", info->mBufferID);
3993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mData->meta()->clear();
39952d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    notify->setBuffer("buffer", info->mData);
3996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec->id());
3998609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    reply->setInt32("buffer-id", info->mBufferID);
3999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setMessage("reply", reply);
4001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->post();
4003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
4005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4007f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
4008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
4009609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
40102d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    sp<ABuffer> buffer;
4011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t err = OK;
40125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool eos = false;
4013a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar    PortMode mode = getPortMode(kPortIndexInput);
40145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40152d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    if (!msg->findBuffer("buffer", &buffer)) {
4016a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar        /* these are unfilled buffers returned by client */
4017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findInt32("err", &err));
4018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
40197fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        if (err == OK) {
40207fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            /* buffers with no errors are returned on MediaCodec.flush */
40217fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            mode = KEEP_BUFFERS;
40227fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        } else {
40237fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            ALOGV("[%s] saw error %d instead of an input buffer",
40247fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                 mCodec->mComponentName.c_str(), err);
40257fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            eos = true;
40267fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        }
40273831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
40282d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber        buffer.clear();
4029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
40315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
40325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
40335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
40345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = ERROR_END_OF_STREAM;
40355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
40365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
4038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_UPSTREAM);
4039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
4041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
40455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (eos) {
4046dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (!mCodec->mPortEOS[kPortIndexInput]) {
4047dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
4048dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mInputEOSResult = err;
4049dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
4050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
40565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
4057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int64_t timeUs;
4058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
4059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
4061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t isCSD;
4063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
4064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
4065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
4066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
40675778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (eos) {
40685778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    flags |= OMX_BUFFERFLAG_EOS;
40695778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
40705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer != info->mData) {
4072d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGV("[%s] Needs to copy input data for buffer %p. (%p != %p)",
4073d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(),
4074d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         bufferID,
4075d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         buffer.get(), info->mData.get());
4076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    CHECK_LE(buffer->size(), info->mData->capacity());
4078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    memcpy(info->mData->data(), buffer->data(), buffer->size());
4079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
4080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4081078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
40823856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ codec specific data",
4083078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID);
40845778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else if (flags & OMX_BUFFERFLAG_EOS) {
40855778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] calling emptyBuffer %p w/ EOS",
40865778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str(), bufferID);
4087078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                } else {
4088d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
4089d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGI("[%s] calling emptyBuffer %p w/ time %lld us",
4090d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
4091d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#else
40923856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ time %lld us",
4093078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
4094d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
4095078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                }
4096349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4097d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
4098d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ACodec::BufferStats stats;
4099d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
4100d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mFillBufferDoneTimeUs = -1ll;
4101d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mCodec->mBufferStats.add(timeUs, stats);
4102d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
4103d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4104054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                if (mCodec->mStoreMetaDataInOutputBuffers) {
4105054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    // try to submit an output buffer for each input buffer
4106054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    PortMode outputMode = getPortMode(kPortIndexOutput);
4107054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4108054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    ALOGV("MetaDataBuffersToSubmit=%u portMode=%s",
4109054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            mCodec->mMetaDataBuffersToSubmit,
4110054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            (outputMode == FREE_BUFFERS ? "FREE" :
4111054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                             outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
4112054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    if (outputMode == RESUBMIT_BUFFERS) {
4113e53350373ac516257b4f8956ff1e3f1ac48f607eLajos Molnar                        mCodec->submitOutputMetaDataBuffer();
4114054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    }
4115054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                }
4116054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
4118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
4119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
4120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
4121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            buffer->size(),
4122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            flags,
4123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            timeUs),
4124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
41285778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (!eos) {
41295778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    getMoreInputDataIfPossible();
41305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
41315778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] Signalled EOS on the input port",
41325778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str());
41335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41345778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
41355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mInputEOSResult = err;
41365778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
4137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
4138dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (err != ERROR_END_OF_STREAM) {
41393856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port "
4140dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         "due to error %d",
4141dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str(), err);
4142dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                } else {
41433856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port",
4144dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str());
4145dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
4146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
41473856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] calling emptyBuffer %p signalling EOS",
4148349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                     mCodec->mComponentName.c_str(), bufferID);
4149349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
4151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
4152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
4153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
4154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
4155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_BUFFERFLAG_EOS,
4156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0),
4157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexInput] = true;
4162dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                mCodec->mInputEOSResult = err;
4163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4166625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih
4167625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih        default:
4168625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
4169625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih            break;
4170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4173f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::getMoreInputDataIfPossible() {
4174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
4175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
4176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *eligible = NULL;
4179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
4181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
4182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
4184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
4185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // There's already a "read" pending.
4186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
4187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
4189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_US) {
4191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            eligible = info;
4192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (eligible == NULL) {
4196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
4197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(eligible);
4200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4202f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXFillBufferDone(
4203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferID,
4204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        size_t rangeOffset, size_t rangeLength,
4205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 flags,
4206784e24e386b088c05d653ab482f2e95cb53e3d01Andy Hung        int64_t timeUs) {
4207609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] onOMXFillBufferDone %u time %" PRId64 " us, flags = 0x%08x",
42085778822d86b0337407514b9372562b86edfa91cdAndreas Huber         mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
4209349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
4211d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4212d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
4213d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    index = mCodec->mBufferStats.indexOfKey(timeUs);
4214d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (index >= 0) {
4215d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
4216d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
4217d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4218d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ALOGI("frame PTS %lld: %lld",
4219d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                timeUs,
4220d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
4221d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4222d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mCodec->mBufferStats.removeItemsAt(index);
4223d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats = NULL;
4224d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
4225d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
4226d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
4228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
4229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
4231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4232054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mDequeuedAt = ++mCodec->mDequeueCounter;
4233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
4234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
4236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4243a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            if (rangeLength == 0 && (!(flags & OMX_BUFFERFLAG_EOS)
4244a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                    || mCodec->mPortEOS[kPortIndexOutput])) {
4245609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                ALOGV("[%s] calling fillBuffer %u",
42465778822d86b0337407514b9372562b86edfa91cdAndreas Huber                     mCodec->mComponentName.c_str(), info->mBufferID);
4247349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
42485778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK_EQ(mCodec->mOMX->fillBuffer(
42495778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mCodec->mNode, info->mBufferID),
42505778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         (status_t)OK);
4251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
42525778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
42535778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
42545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
425531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4256577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            sp<AMessage> reply =
4257577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                new AMessage(kWhatOutputBufferDrained, mCodec->id());
4258577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
42594bdda35319d5f46efea2089b865c8a64816389cdMarco Nelissen            if (!mCodec->mSentFormat && rangeLength > 0) {
4260577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->sendFormatChange(reply);
42615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
4262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4263308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            if (mCodec->mUseMetadataOnEncoderOutput) {
4264308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                native_handle_t* handle =
4265308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        *(native_handle_t**)(info->mData->data() + 4);
4266308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setPointer("handle", handle);
4267308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeOffset", rangeOffset);
4268308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeLength", rangeLength);
4269308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            } else {
4270308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->setRange(rangeOffset, rangeLength);
4271308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            }
4272496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#if 0
427321ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen            if (mCodec->mNativeWindow == NULL) {
4274496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                if (IsIDR(info->mData)) {
4275496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                    ALOGI("IDR frame");
4276496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                }
42775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
427821ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen#endif
4279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
42808b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            if (mCodec->mSkipCutBuffer != NULL) {
42818b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                mCodec->mSkipCutBuffer->submit(info->mData);
42828b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            }
42835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mData->meta()->setInt64("timeUs", timeUs);
4284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
42855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4286d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatDrainThisBuffer);
4287609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            notify->setInt32("buffer-id", info->mBufferID);
42882d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            notify->setBuffer("buffer", info->mData);
42895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("flags", flags);
4290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4291609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            reply->setInt32("buffer-id", info->mBufferID);
4292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
42935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setMessage("reply", reply);
4294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
42955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->post();
42965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
42975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
4298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (flags & OMX_BUFFERFLAG_EOS) {
43005778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
43015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                sp<AMessage> notify = mCodec->mNotify->dup();
4303d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar                notify->setInt32("what", CodecBase::kWhatEOS);
4304dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                notify->setInt32("err", mCodec->mInputEOSResult);
4305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->post();
4306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexOutput] = true;
4308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
4315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
4317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
4318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4325f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
4326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
4327609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
4328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
4329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
4330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
4331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM);
4332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4333577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    android_native_rect_t crop;
4334577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    if (msg->findRect("crop",
4335577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            &crop.left, &crop.top, &crop.right, &crop.bottom)) {
4336577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar        CHECK_EQ(0, native_window_set_crop(
4337577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->mNativeWindow.get(), &crop));
4338577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    }
4339577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
4340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t render;
4341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mNativeWindow != NULL
43426aade6058521b0dbd35a9a4620f4d04f02f90444Marco Nelissen            && msg->findInt32("render", &render) && render != 0
434379ee2399b67c7a11042c5904dc1309712a76f8cbJianzheng Zhou            && info->mData != NULL && info->mData->size() != 0) {
43446fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        ATRACE_NAME("render");
4345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The client wants this buffer to be rendered.
4346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4347fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        int64_t timestampNs = 0;
4348fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        if (!msg->findInt64("timestampNs", &timestampNs)) {
4349fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // TODO: it seems like we should use the timestamp
4350fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // in the (media)buffer as it potentially came from
4351fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // an input surface, but we did not propagate it prior to
4352fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // API 20.  Perhaps check for target SDK version.
4353fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#if 0
4354fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            if (info->mData->meta()->findInt64("timeUs", &timestampNs)) {
435547aea1f7c58f5302b16822f9e7e1763f2af04ef5Lajos Molnar                ALOGV("using buffer PTS of %" PRId64, timestampNs);
4356fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar                timestampNs *= 1000;
4357fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            }
4358fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#endif
4359fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
4360fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
43615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err;
4362fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        err = native_window_set_buffers_timestamp(mCodec->mNativeWindow.get(), timestampNs);
4363fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        if (err != OK) {
4364fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            ALOGW("failed to set buffer timestamp: %d", err);
4365fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
4366fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
43675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if ((err = mCodec->mNativeWindow->queueBuffer(
4368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNativeWindow.get(),
43691e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                    info->mGraphicBuffer.get(), -1)) == OK) {
4370cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
4371cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        } else {
4372251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
4373cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
4374cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        }
4375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
43766fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        if (mCodec->mNativeWindow != NULL &&
43776fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar            (info->mData == NULL || info->mData->size() != 0)) {
43786fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar            ATRACE_NAME("frame-drop");
43796fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        }
4380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_US;
4381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
4384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
4389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // We cannot resubmit the buffer we just rendered, dequeue
4392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // the spare instead.
4393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info = mCodec->dequeueBufferFromNativeWindow();
4395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (!mCodec->mPortEOS[kPortIndexOutput]) {
4402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // We cannot resubmit the buffer we just rendered, dequeue
4404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // the spare instead.
4405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info = mCodec->dequeueBufferFromNativeWindow();
4407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
4408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4409c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                if (info != NULL) {
4410609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                    ALOGV("[%s] calling fillBuffer %u",
4411c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                         mCodec->mComponentName.c_str(), info->mBufferID);
4412349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4413c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
4414c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                             (status_t)OK);
4415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4416c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4417c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                }
4418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
4425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
4427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
4428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4435f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::UninitializedState::UninitializedState(ACodec *codec)
4436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4439c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::UninitializedState::stateEntered() {
4440c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("Now uninitialized");
4441ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4442ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (mDeathNotifier != NULL) {
4443ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mCodec->mOMX->asBinder()->unlinkToDeath(mDeathNotifier);
4444ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
4445ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
4446ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4447ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNativeWindow.clear();
4448ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNode = NULL;
4449ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mOMX.clear();
4450ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mQuirks = 0;
4451ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mFlags = 0;
4452308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    mCodec->mUseMetadataOnEncoderOutput = 0;
4453ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mComponentName.clear();
4454c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4455c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4456f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
4457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatSetup:
4461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onSetup(msg);
4463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
44685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case ACodec::kWhatAllocateComponent:
44695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
44705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            onAllocateComponent(msg);
44715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            handled = true;
44725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
44735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
44745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatShutdown:
4476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4477c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
4478c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
4479c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
448054b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            ALOGW_IF(keepComponentAllocated,
448154b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar                     "cannot keep component allocated on shutdown in Uninitialized state");
4482c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4484d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
4485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
4486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4488c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
4489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatFlush:
4492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4494d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
4495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
4496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4498c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
4499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
450130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        case ACodec::kWhatReleaseCodecInstance:
450230358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        {
450330358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            // nothing to do, as we have already signaled shutdown
450430358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            handled = true;
450530358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            break;
450630358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        }
450730358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar
4508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
4510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4515f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::UninitializedState::onSetup(
4516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4517c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (onAllocateComponent(msg)
4518c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            && mCodec->mLoadedState->onConfigureComponent(msg)) {
4519c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mLoadedState->onStart();
4520c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
45215778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
45225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4523c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
45245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onAllocateComponent");
45255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4526c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    CHECK(mCodec->mNode == NULL);
45275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMXClient client;
4529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(client.connect(), (status_t)OK);
4530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<IOMX> omx = client.interface();
4532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4533ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec->id());
4534ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4535ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mDeathNotifier = new DeathNotifier(notify);
4536ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (omx->asBinder()->linkToDeath(mDeathNotifier) != OK) {
4537ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // This was a local binder, if it dies so do we, we won't care
4538ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // about any notifications in the afterlife.
4539ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
4540ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
4541ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4542e671207115fac3914134c61b336d5fa0242c68caAndreas Huber    Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs;
45435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    AString mime;
4545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
45465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString componentName;
4547d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint32_t quirks = 0;
45487791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen    int32_t encoder = false;
45495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findString("componentName", &componentName)) {
4550e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        ssize_t index = matchingCodecs.add();
4551e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        OMXCodec::CodecNameAndQuirks *entry = &matchingCodecs.editItemAt(index);
4552e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        entry->mName = String8(componentName.c_str());
4553afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
4554e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        if (!OMXCodec::findCodecQuirks(
4555e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                    componentName.c_str(), &entry->mQuirks)) {
4556e671207115fac3914134c61b336d5fa0242c68caAndreas Huber            entry->mQuirks = 0;
4557afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
45585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
45595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(msg->findString("mime", &mime));
45605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
45615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("encoder", &encoder)) {
45625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder = false;
45635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
45645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
45655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMXCodec::findMatchingCodecs(
45665778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mime.c_str(),
45675778822d86b0337407514b9372562b86edfa91cdAndreas Huber                encoder, // createEncoder
45685778822d86b0337407514b9372562b86edfa91cdAndreas Huber                NULL,  // matchComponentName
45695778822d86b0337407514b9372562b86edfa91cdAndreas Huber                0,     // flags
4570e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                &matchingCodecs);
45715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
45721065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
45731065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    sp<CodecObserver> observer = new CodecObserver;
45741065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    IOMX::node_id node = NULL;
45751065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
45761065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
45771065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            ++matchIndex) {
4578e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        componentName = matchingCodecs.itemAt(matchIndex).mName.string();
4579e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        quirks = matchingCodecs.itemAt(matchIndex).mQuirks;
4580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4581078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        pid_t tid = androidGetTid();
4582078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        int prevPriority = androidGetThreadPriority(tid);
4583078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
45841065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        status_t err = omx->allocateNode(componentName.c_str(), observer, &node);
4585078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, prevPriority);
4586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
45871065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        if (err == OK) {
45881065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            break;
45897a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He        } else {
45907a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He            ALOGW("Allocating component '%s' failed, try next one.", componentName.c_str());
45911065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
45921065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
45931065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        node = NULL;
45941065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    }
45951065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
4596c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    if (node == NULL) {
45975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!mime.empty()) {
45987791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen            ALOGE("Unable to instantiate a %scoder for type '%s'.",
45997791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen                    encoder ? "en" : "de", mime.c_str());
46005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
46017791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen            ALOGE("Unable to instantiate codec '%s'.", componentName.c_str());
46025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
4603c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
4604cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        mCodec->signalError(OMX_ErrorComponentNotFound);
4605c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
4606c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
4607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4608ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    notify = new AMessage(kWhatOMXMessage, mCodec->id());
4609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    observer->setNotificationMessage(notify);
4610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mComponentName = componentName;
4612ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    mCodec->mFlags = 0;
4613ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
4614ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (componentName.endsWith(".secure")) {
4615ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        mCodec->mFlags |= kFlagIsSecure;
46160167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
4617ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
4618ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
4619afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mCodec->mQuirks = quirks;
4620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mOMX = omx;
4621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mNode = node;
4622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
46235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
46245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
4625d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatComponentAllocated);
46265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setString("componentName", mCodec->mComponentName.c_str());
46275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
46285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4629c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4630c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mCodec->changeState(mCodec->mLoadedState);
4631c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4632c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
46335778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
46345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4635c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
4636c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4637c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas HuberACodec::LoadedState::LoadedState(ACodec *codec)
4638c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    : BaseState(codec) {
4639c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4640c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4641c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::stateEntered() {
4642c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
4643c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4644f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mPortEOS[kPortIndexInput] =
4645f6f38287b97ec69b169387add6458f859b770e65Andreas Huber        mCodec->mPortEOS[kPortIndexOutput] = false;
4646f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
4647f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mInputEOSResult = OK;
4648f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
4649054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mDequeueCounter = 0;
4650054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mMetaDataBuffersToSubmit = 0;
4651a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    mCodec->mRepeatFrameDelayUs = -1ll;
4652e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mInputFormat.clear();
4653e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mOutputFormat.clear();
46544e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    mCodec->mBaseOutputFormat.clear();
4655054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4656c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (mCodec->mShutdownInProgress) {
4657c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
4658c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4659c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mShutdownInProgress = false;
4660c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mKeepComponentAllocated = false;
4661c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4662c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        onShutdown(keepComponentAllocated);
4663c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
466454b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    mCodec->mExplicitShutdown = false;
4665f393c33e65ae51a7cf168b4e15771b152f996b32Wei Jia
4666f393c33e65ae51a7cf168b4e15771b152f996b32Wei Jia    mCodec->processDeferredMessages();
4667c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4668c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4669c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
4670c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (!keepComponentAllocated) {
4671c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK);
4672c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4673c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->changeState(mCodec->mUninitializedState);
4674c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
4675c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
467654b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    if (mCodec->mExplicitShutdown) {
467754b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        sp<AMessage> notify = mCodec->mNotify->dup();
4678d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
467954b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        notify->post();
468054b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        mCodec->mExplicitShutdown = false;
468154b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    }
4682c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4683c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4684c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
4685c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool handled = false;
4686c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4687c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    switch (msg->what()) {
4688c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatConfigureComponent:
4689c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
4690c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onConfigureComponent(msg);
4691c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
4692c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
4693c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
4694c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
46957cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
46967cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
46977cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            onCreateInputSurface(msg);
46987cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
46997cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
47007cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
47017cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4702c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatStart:
4703c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
4704c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onStart();
4705c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
4706c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
4707c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
4708c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4709c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatShutdown:
4710c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
4711c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
4712c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
4713c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
4714c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
471554b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
4716c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onShutdown(keepComponentAllocated);
4717c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4718c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
4719c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
4720c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
4721c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4722c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatFlush:
4723c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
4724c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4725d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
4726c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->post();
4727c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4728c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
4729c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
4730c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
4731c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4732c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        default:
4733c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            return BaseState::onMessageReceived(msg);
4734c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
4735c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4736c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return handled;
4737c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4738c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4739c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onConfigureComponent(
47405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg) {
47415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onConfigureComponent");
47425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
47435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(mCodec->mNode != NULL);
47445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
47455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString mime;
47465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findString("mime", &mime));
47475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
47485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mCodec->configureCodec(mime.c_str(), msg);
47495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
47505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
4751c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        ALOGE("[%s] configureCodec returning error %d",
4752c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber              mCodec->mComponentName.c_str(), err);
4753c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber
4754251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
4755c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
47565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<RefBase> obj;
4759386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    if (msg->findObject("native-window", &obj)
47605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            && strncmp("OMX.google.", mCodec->mComponentName.c_str(), 11)) {
47611173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        sp<NativeWindowWrapper> nativeWindow(
47621173118eace0e9e347cb007f0da817cee87579edGlenn Kasten                static_cast<NativeWindowWrapper *>(obj.get()));
47631173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        CHECK(nativeWindow != NULL);
47641173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        mCodec->mNativeWindow = nativeWindow->getNativeWindow();
47651ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber
47661ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber        native_window_set_scaling_mode(
47671ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                mCodec->mNativeWindow.get(),
47681ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
4769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((status_t)OK, mCodec->initNativeWindow());
4771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
47725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
47735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
4774d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatComponentConfigured);
4775e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("input-format", mCodec->mInputFormat);
4776e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("output-format", mCodec->mOutputFormat);
47775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
47785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4779c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4780c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
47815778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
47825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
47837cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::LoadedState::onCreateInputSurface(
4784ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        const sp<AMessage> & /* msg */) {
47857cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    ALOGV("onCreateInputSurface");
47867cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
47877cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<AMessage> notify = mCodec->mNotify->dup();
4788d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatInputSurfaceCreated);
47897cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
47907cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<IGraphicBufferProducer> bufferProducer;
47917cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    status_t err;
47927cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
47937cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    err = mCodec->mOMX->createInputSurface(mCodec->mNode, kPortIndexInput,
47947cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            &bufferProducer);
4795a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
4796a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    if (err == OK && mCodec->mRepeatFrameDelayUs > 0ll) {
4797a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        err = mCodec->mOMX->setInternalOption(
4798a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                mCodec->mNode,
4799a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                kPortIndexInput,
4800a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY,
4801a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                &mCodec->mRepeatFrameDelayUs,
4802a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                sizeof(mCodec->mRepeatFrameDelayUs));
4803a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
4804a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (err != OK) {
4805a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            ALOGE("[%s] Unable to configure option to repeat previous "
4806a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  "frames (err %d)",
4807a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  mCodec->mComponentName.c_str(),
4808a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  err);
4809a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
4810a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
4811a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
48122c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    if (err == OK && mCodec->mMaxPtsGapUs > 0ll) {
481394ee4b708acfa941581160b267afb79192b1d816Chong Zhang        err = mCodec->mOMX->setInternalOption(
481494ee4b708acfa941581160b267afb79192b1d816Chong Zhang                mCodec->mNode,
481594ee4b708acfa941581160b267afb79192b1d816Chong Zhang                kPortIndexInput,
481694ee4b708acfa941581160b267afb79192b1d816Chong Zhang                IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP,
481794ee4b708acfa941581160b267afb79192b1d816Chong Zhang                &mCodec->mMaxPtsGapUs,
481894ee4b708acfa941581160b267afb79192b1d816Chong Zhang                sizeof(mCodec->mMaxPtsGapUs));
481994ee4b708acfa941581160b267afb79192b1d816Chong Zhang
482094ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (err != OK) {
482194ee4b708acfa941581160b267afb79192b1d816Chong Zhang            ALOGE("[%s] Unable to configure max timestamp gap (err %d)",
482272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    mCodec->mComponentName.c_str(),
482372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    err);
48242c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
48252c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
48262c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
48272c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    if (err == OK && mCodec->mTimePerCaptureUs > 0ll
48282c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            && mCodec->mTimePerFrameUs > 0ll) {
48292c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        int64_t timeLapse[2];
48302c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[0] = mCodec->mTimePerFrameUs;
48312c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[1] = mCodec->mTimePerCaptureUs;
48322c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        err = mCodec->mOMX->setInternalOption(
48332c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                mCodec->mNode,
48342c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                kPortIndexInput,
48352c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                IOMX::INTERNAL_OPTION_TIME_LAPSE,
48362c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                &timeLapse[0],
48372c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                sizeof(timeLapse));
48382c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
48392c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (err != OK) {
48402c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            ALOGE("[%s] Unable to configure time lapse (err %d)",
48412c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    mCodec->mComponentName.c_str(),
48422c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    err);
48432c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
48442c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
484572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
484672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (err == OK && mCodec->mCreateInputBuffersSuspended) {
484772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        bool suspend = true;
484872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        err = mCodec->mOMX->setInternalOption(
484972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                mCodec->mNode,
485072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                kPortIndexInput,
485172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                IOMX::INTERNAL_OPTION_SUSPEND,
485272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                &suspend,
485372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                sizeof(suspend));
485472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
485572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
485672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("[%s] Unable to configure option to suspend (err %d)",
485794ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  mCodec->mComponentName.c_str(),
485894ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  err);
485994ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
486094ee4b708acfa941581160b267afb79192b1d816Chong Zhang    }
486194ee4b708acfa941581160b267afb79192b1d816Chong Zhang
48627cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err == OK) {
48637cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setObject("input-surface",
48647cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                new BufferProducerWrapper(bufferProducer));
48657cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else {
48667cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // Can't use mCodec->signalError() here -- MediaCodec won't forward
48677cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // the error through because it's in the "configured" state.  We
48687cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // send a kWhatInputSurfaceCreated with an error value instead.
48697cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGE("[%s] onCreateInputSurface returning error %d",
48707cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                mCodec->mComponentName.c_str(), err);
48717cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setInt32("err", err);
48727cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
48737cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->post();
48747cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
48757cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4876c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onStart() {
48775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onStart");
48785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
48795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ(mCodec->mOMX->sendCommand(
48805778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
4881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
4882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->changeState(mCodec->mLoadedToIdleState);
4884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4888f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
4889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4892f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::LoadedToIdleState::stateEntered() {
48933856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
4894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4895cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    status_t err;
4896cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    if ((err = allocateBuffers()) != OK) {
489729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to allocate buffers after transitioning to IDLE state "
4898cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             "(error 0x%08x)",
4899cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             err);
4900cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
4901251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
490291bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber
490391bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber        mCodec->changeState(mCodec->mLoadedState);
4904cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    }
4905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4907f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::LoadedToIdleState::allocateBuffers() {
4908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
4909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
4911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
4912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mCodec->allocateBuffersOnPort(kPortIndexOutput);
4915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4917f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
4918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
491972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
4920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
49266507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
49276507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
49286507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
49296507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
49306507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
49316507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
49326463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatResume:
49336463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
49346463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We'll be active soon enough.
49356463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
49366463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
49376463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
49386463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatFlush:
49396463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
49406463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We haven't even started yet, so we're flushed alright...
49416463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            sp<AMessage> notify = mCodec->mNotify->dup();
4942d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
49436463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->post();
49446463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
49456463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
49466463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
4947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
4949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4952f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onOMXEvent(
4953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
4959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
4961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting),
4962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
4963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mIdleToExecutingState);
4965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4976f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
4977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4980f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToExecutingState::stateEntered() {
49813856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
4982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4984f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
4985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
498672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
4987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4993d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatResume:
4994d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
4995d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We'll be active soon enough.
4996d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
4997d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
4998d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
4999d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatFlush:
5000d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
5001d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We haven't even started yet, so we're flushed alright...
5002d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
5003d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
5004d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->post();
5005d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
5006d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
5007d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
5008d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
50096507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
50106507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
50116507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
50126507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
50136507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
50146507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
5015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
5017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5020f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onOMXEvent(
5021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
5026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateExecuting);
5027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mExecutingState->resume();
5029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingState);
5030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5041f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingState::ExecutingState(ACodec *codec)
5042349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    : BaseState(codec),
5043349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber      mActive(false) {
5044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5046f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
5047ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
5048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
5049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5051054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputMetaBuffers() {
5052054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // submit as many buffers as there are input buffers with the codec
5053054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // in case we are in port reconfiguring
5054054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
5055054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
5056054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5057054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) {
5058054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            if (mCodec->submitOutputMetaDataBuffer() != OK)
5059054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                break;
5060054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
5061054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
50624dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
50634dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
50644dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
5065054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
5066054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5067054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitRegularOutputBuffers() {
5068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
5069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
5070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mCodec->mNativeWindow != NULL) {
5072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(info->mStatus == BufferInfo::OWNED_BY_US
5073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
5074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
5076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                continue;
5077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
5079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
5080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5081f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
50823856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] calling fillBuffer %p",
5083349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str(), info->mBufferID);
5084349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
5086f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
5087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
5089f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5092054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputBuffers() {
5093c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar    submitRegularOutputBuffers();
5094054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mCodec->mStoreMetaDataInOutputBuffers) {
5095054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        submitOutputMetaBuffers();
5096054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
5097054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
5098054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5099f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::resume() {
5100349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    if (mActive) {
51013856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] We're already active, no need to resume.",
5102349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str());
5103349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5104349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        return;
5105349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    }
5106349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    submitOutputBuffers();
5108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
51093cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    // Post all available input buffers
5110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_GT(mCodec->mBuffers[kPortIndexInput].size(), 0u);
51113cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); i++) {
51123cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
51133cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_US) {
51143cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar            postFillThisBuffer(info);
51153cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        }
51163cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    }
5117349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5118349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    mActive = true;
5119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5121f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::stateEntered() {
51223856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
5123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->processDeferredMessages();
5125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5127f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
5128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5133c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
5134c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
5135c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
5136c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5137c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mShutdownInProgress = true;
513854b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
5139c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mKeepComponentAllocated = keepComponentAllocated;
5140c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5141349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
5142349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
5144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
5145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
5146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingToIdleState);
5148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
51557a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong            ALOGV("[%s] ExecutingState flushing now "
5156d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                 "(codec owns %d/%d input, %d/%d output).",
5157d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mComponentName.c_str(),
5158d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
5159d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexInput].size(),
5160d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
5161d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexOutput].size());
5162d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
5163349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
5164349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
5166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandFlush, OMX_ALL),
5167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
5168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mFlushingState);
5170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatResume:
5175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            resume();
5177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5182496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
5183496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
5184496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            status_t err = mCodec->requestIDRFrame();
5185496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            if (err != OK) {
5186496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                ALOGW("Requesting an IDR frame failed.");
5187496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            }
5188496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5189496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            handled = true;
5190496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
5191496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
5192496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5193a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
5194a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
5195a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
5196a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
5197a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5198a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = mCodec->setParameters(params);
5199a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5200a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> reply;
5201a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            if (msg->findMessage("reply", &reply)) {
5202a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->setInt32("err", err);
5203a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->post();
5204a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            }
5205a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5206a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            handled = true;
5207a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
5208a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
5209a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
52107cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
52117cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
52126507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
52137cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
52147cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
52157cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
52167cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
52174dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
52184dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        case kWhatSubmitOutputMetaDataBufferIfEOS:
52194dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        {
52204dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            if (mCodec->mPortEOS[kPortIndexInput] &&
52214dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    !mCodec->mPortEOS[kPortIndexOutput]) {
52224dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                status_t err = mCodec->submitOutputMetaDataBuffer();
52234dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                if (err == OK) {
52244dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
52254dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                }
52264dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            }
52274dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            return true;
52284dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        }
52294dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
5230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5238a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t ACodec::setParameters(const sp<AMessage> &params) {
5239a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    int32_t videoBitrate;
5240530fdbdc1b5491f3fbf172752834d1515701e142Lajos Molnar    if (params->findInt32("video-bitrate", &videoBitrate)) {
5241a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        OMX_VIDEO_CONFIG_BITRATETYPE configParams;
5242a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        InitOMXParams(&configParams);
5243a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nPortIndex = kPortIndexOutput;
5244a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nEncodeBitrate = videoBitrate;
5245a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5246a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        status_t err = mOMX->setConfig(
5247a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                mNode,
5248a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                OMX_IndexConfigVideoBitrate,
5249a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                &configParams,
5250a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                sizeof(configParams));
5251a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5252a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        if (err != OK) {
5253a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
5254a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                   videoBitrate, err);
5255a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5256a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            return err;
5257a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
5258a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    }
5259a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
526072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    int64_t skipFramesBeforeUs;
526172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (params->findInt64("skip-frames-before", &skipFramesBeforeUs)) {
526272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        status_t err =
526372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mOMX->setInternalOption(
526472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     mNode,
526572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     kPortIndexInput,
526672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     IOMX::INTERNAL_OPTION_START_TIME,
526772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     &skipFramesBeforeUs,
526872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     sizeof(skipFramesBeforeUs));
526972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
527072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
527172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("Failed to set parameter 'skip-frames-before' (err %d)", err);
527272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            return err;
527372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
527472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
527572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
5276e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    int32_t dropInputFrames;
5277e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    if (params->findInt32("drop-input-frames", &dropInputFrames)) {
5278e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        bool suspend = dropInputFrames != 0;
5279e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
5280b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err =
5281b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            mOMX->setInternalOption(
5282e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     mNode,
5283e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     kPortIndexInput,
5284e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     IOMX::INTERNAL_OPTION_SUSPEND,
5285e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     &suspend,
5286b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber                     sizeof(suspend));
5287b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
5288b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
5289b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err);
5290b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
5291b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
5292b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    }
5293b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
5294b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    int32_t dummy;
5295b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    if (params->findInt32("request-sync", &dummy)) {
5296b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err = requestIDRFrame();
5297b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
5298b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
5299b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Requesting a sync frame failed w/ err %d", err);
5300b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
5301b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
5302e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    }
5303e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
5304a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return OK;
5305a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
5306a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
53076507d14c6d10f93d390de62b9eed267f9b544985Andy McFaddenvoid ACodec::onSignalEndOfInputStream() {
53086507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    sp<AMessage> notify = mNotify->dup();
5309d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatSignaledInputEOS);
53106507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
53116507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    status_t err = mOMX->signalEndOfInputStream(mNode);
53126507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    if (err != OK) {
53136507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        notify->setInt32("err", err);
53146507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    }
53156507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->post();
53166507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden}
53176507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
5318f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onOMXEvent(
5319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventPortSettingsChanged:
5322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
5324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
532531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
5326054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mCodec->mMetaDataBuffersToSubmit = 0;
5327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
5328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
5329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_CommandPortDisable, kPortIndexOutput),
5330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
5331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5332349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                mCodec->freeOutputBuffersNotOwnedByComponent();
5333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
533531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            } else if (data2 == OMX_IndexConfigCommonOutputCrop) {
533631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
5337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
53383856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08lx",
5339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->mComponentName.c_str(), data2);
5340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventBufferFlag:
5346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5357f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
5358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ACodec *codec)
5359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5362f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
5363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
5364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput) {
5365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return FREE_BUFFERS;
5366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
5369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
5371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5373f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onMessageReceived(
5374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
5375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5380349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case kWhatResume:
5381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5382349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            if (msg->what() == kWhatResume) {
53833856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
5384349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            }
5385349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
5387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5399f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::OutputPortSettingsChangedState::stateEntered() {
54003856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now handling output port settings change",
5401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mCodec->mComponentName.c_str());
5402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5404f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onOMXEvent(
5405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
5410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
5411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
54123856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now disabled.",
5413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
5414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mCodec->mBuffers[kPortIndexOutput].isEmpty());
5416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mDealer[kPortIndexOutput].clear();
5417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
5419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput),
5420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
5421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5422cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                status_t err;
5423cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                if ((err = mCodec->allocateBuffersOnPort(
5424cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                                kPortIndexOutput)) != OK) {
542529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("Failed to allocate output port buffers after "
5426cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         "port reconfiguration (error 0x%08x)",
5427cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         err);
5428cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
5429251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5430d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
5431755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // This is technically not correct, but appears to be
5432755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the only way to free the component instance.
5433755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // Controlled transitioning from excecuting->idle
5434755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // and idle->loaded seem impossible probably because
5435755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the output port never finishes re-enabling.
5436755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mShutdownInProgress = true;
5437755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mKeepComponentAllocated = false;
5438755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->changeState(mCodec->mLoadedState);
5439cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                }
5440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
5442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
5443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
5444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
544531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
544631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
54473856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now reenabled.",
5448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
5449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5450349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                if (mCodec->mExecutingState->active()) {
5451349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    mCodec->mExecutingState->submitOutputBuffers();
5452349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                }
5453349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mExecutingState);
5455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
5457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
5460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
5464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5469f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
54705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : BaseState(codec),
54715778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mComponentNowIdle(false) {
5472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5474f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
5475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
5481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
5482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
5483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
5489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5502f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::stateEntered() {
55033856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
550431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
55055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mComponentNowIdle = false;
550631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mCodec->mSentFormat = false;
5507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5509f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onOMXEvent(
5510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
5515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
5516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
55175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mComponentNowIdle = true;
55185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            changeStateIfWeOwnAllBuffers();
5520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5524349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
5525349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventBufferFlag:
5526349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
5527349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We're shutting down and don't care about this anymore.
5528349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
5529349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
5530349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
55350af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
5536f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
55375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
5538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->sendCommand(
5539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded),
5540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
5541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexInput), (status_t)OK);
5543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexOutput), (status_t)OK);
5544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
55450167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown)
55460167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && mCodec->mNativeWindow != NULL) {
5547bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // We push enough 1x1 blank buffers to ensure that one of
5548bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // them has made it to the display.  This allows the OMX
5549bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // component teardown to zero out any protected buffers
5550bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // without the risk of scanning out one of those buffers.
5551bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            mCodec->pushBlankBuffersToNativeWindow();
5552bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
5553bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
5554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mIdleToLoadedState);
5555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5558f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onInputBufferFilled(
5559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
5560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
5561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
5563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5565f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onOutputBufferDrained(
5566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
5567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
5568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
5570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5574f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
5575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5578f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
5579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
5585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
5593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
5594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
5595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5606f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToLoadedState::stateEntered() {
56073856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
5608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5610f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onOMXEvent(
5611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
5616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateLoaded);
5617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5618c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->changeState(mCodec->mLoadedState);
5619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5630f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::FlushingState::FlushingState(ACodec *codec)
5631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5634f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::stateEntered() {
56353856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
5636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
5638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5640f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
5641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
5647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing this right now.
5653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5665f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onOMXEvent(
5666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
56677a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] FlushingState onOMXEvent(%d,%ld)",
5668d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            mCodec->mComponentName.c_str(), event, data1);
5669d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
5670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandFlush);
5674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
5676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(!mFlushComplete[data2]);
5677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mFlushComplete[data2] = true;
5678e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber
5679e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                if (mFlushComplete[kPortIndexInput]
5680e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                        && mFlushComplete[kPortIndexOutput]) {
5681e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                    changeStateIfWeOwnAllBuffers();
5682e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                }
5683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
5684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, OMX_ALL);
5685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexInput]);
5686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexOutput]);
5687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                changeStateIfWeOwnAllBuffers();
5689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5694349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
5695349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
5696349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec->id());
5697349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("type", omx_message::EVENT);
5698609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            msg->setInt32("node", mCodec->mNode);
5699349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("event", event);
5700349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data1", data1);
5701349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data2", data2);
5702349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
57033856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
5704349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                 mCodec->mComponentName.c_str());
5705349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5706349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mCodec->deferMessage(msg);
5707349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5708349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
5709349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
5710349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
5716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5718f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
5719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
5720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
5722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5724f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
5725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
5726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
5728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5730f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
5731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mFlushComplete[kPortIndexInput]
5732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mFlushComplete[kPortIndexOutput]
5733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mCodec->allYourBuffersAreBelongToUs()) {
57347e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // We now own all buffers except possibly those still queued with
57357e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // the native window for rendering. Let's get those back as well.
57367e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
57377e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
5738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
5739d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatFlushCompleted);
5740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->post();
5741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->mPortEOS[kPortIndexInput] =
5743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mPortEOS[kPortIndexOutput] = false;
5744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5745dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber        mCodec->mInputEOSResult = OK;
5746dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
5747f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        if (mCodec->mSkipCutBuffer != NULL) {
5748f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen            mCodec->mSkipCutBuffer->clear();
5749f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        }
5750f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen
5751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mExecutingState);
5752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
5756