ACodec.cpp revision a147b4f91143d9f2fb608e22f9fca14bbd029573
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),
42472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang      mCreateInputBuffersSuspended(false) {
425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mUninitializedState = new UninitializedState(this);
426c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mLoadedState = new LoadedState(this);
427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mLoadedToIdleState = new LoadedToIdleState(this);
428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToExecutingState = new IdleToExecutingState(this);
429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingState = new ExecutingState(this);
430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOutputPortSettingsChangedState =
432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        new OutputPortSettingsChangedState(this);
433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingToIdleState = new ExecutingToIdleState(this);
435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToLoadedState = new IdleToLoadedState(this);
436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushingState = new FlushingState(this);
437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
439dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber    mInputEOSResult = OK;
440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeState(mUninitializedState);
442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
444f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::~ACodec() {
445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
447f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::setNotificationMessage(const sp<AMessage> &msg) {
448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mNotify = msg;
449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
451f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::initiateSetup(const sp<AMessage> &msg) {
452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setWhat(kWhatSetup);
453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setTarget(id());
454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
457a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Hubervoid ACodec::signalSetParameters(const sp<AMessage> &params) {
458a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    sp<AMessage> msg = new AMessage(kWhatSetParameters, id());
459a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->setMessage("params", params);
460a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->post();
461a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
462a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4635778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateAllocateComponent(const sp<AMessage> &msg) {
4645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatAllocateComponent);
4655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
4665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4675778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4695778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateConfigureComponent(const sp<AMessage> &msg) {
4705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatConfigureComponent);
4715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
4725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4735778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4757cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::initiateCreateInputSurface() {
4767cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    (new AMessage(kWhatCreateInputSurface, id()))->post();
4777cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
4787cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4797cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::signalEndOfInputStream() {
4807cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    (new AMessage(kWhatSignalEndOfInputStream, id()))->post();
4817cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
4827cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4835778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateStart() {
4845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    (new AMessage(kWhatStart, id()))->post();
4855778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
487f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalFlush() {
4887a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] signalFlush", mComponentName.c_str());
489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatFlush, id()))->post();
490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
492f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalResume() {
493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatResume, id()))->post();
494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
496c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::initiateShutdown(bool keepComponentAllocated) {
497c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> msg = new AMessage(kWhatShutdown, id());
498c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->setInt32("keepComponentAllocated", keepComponentAllocated);
499c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->post();
500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
502496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubervoid ACodec::signalRequestIDRFrame() {
503496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    (new AMessage(kWhatRequestIDRFrame, id()))->post();
504496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
505496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5064dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
5074dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// Some codecs may return input buffers before having them processed.
5084dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// This causes a halt if we already signaled an EOS on the input
5094dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// port.  For now keep submitting an output buffer if there was an
5104dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// EOS on the input port, but not yet on the output port.
5114dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnarvoid ACodec::signalSubmitOutputMetaDataBufferIfEOS_workaround() {
5124dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    if (mPortEOS[kPortIndexInput] && !mPortEOS[kPortIndexOutput] &&
5134dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            mMetaDataBuffersToSubmit > 0) {
5144dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        (new AMessage(kWhatSubmitOutputMetaDataBufferIfEOS, id()))->post();
5154dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    }
5164dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar}
5174dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
518f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mDealer[portIndex] == NULL);
522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mBuffers[portIndex].isEmpty());
523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
526054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (mStoreMetaDataInOutputBuffers) {
527054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputMetaDataBuffers();
528054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
529054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputBuffersFromNativeWindow();
530054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
5315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
5325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
5335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
5345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = portIndex;
535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
5375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err == OK) {
540609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGV("[%s] Allocating %u buffers of size %u on %s port",
5415778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mComponentName.c_str(),
5425778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    def.nBufferCountActual, def.nBufferSize,
5435778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    portIndex == kPortIndexInput ? "input" : "output");
544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            size_t totalSize = def.nBufferCountActual * def.nBufferSize;
5465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
5495778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
5505778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(mem.get() != NULL);
551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
552ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                BufferInfo info;
553ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                info.mStatus = BufferInfo::OWNED_BY_US;
554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
555afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                uint32_t requiresAllocateBufferBit =
556afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                    (portIndex == kPortIndexInput)
557afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        ? OMXCodec::kRequiresAllocateBufferOnInputPorts
558afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        : OMXCodec::kRequiresAllocateBufferOnOutputPorts;
5591065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
560308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                if ((portIndex == kPortIndexInput && (mFlags & kFlagIsSecure))
561308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        || mUseMetadataOnEncoderOutput) {
562ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    mem.clear();
563ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
564ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    void *ptr;
565ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->allocateBuffer(
566ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, def.nBufferSize, &info.mBufferID,
567ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            &ptr);
568ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
569308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    int32_t bufSize = mUseMetadataOnEncoderOutput ?
570308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                            (4 + sizeof(buffer_handle_t)) : def.nBufferSize;
571308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
572308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    info.mData = new ABuffer(ptr, bufSize);
573ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                } else if (mQuirks & requiresAllocateBufferBit) {
5745778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    err = mOMX->allocateBufferWithBackup(
575ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, mem, &info.mBufferID);
5765778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
577ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->useBuffer(mNode, portIndex, mem, &info.mBufferID);
578ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                }
579ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
580ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                if (mem != NULL) {
581ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    info.mData = new ABuffer(mem->pointer(), def.nBufferSize);
5825778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
5831065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
5845778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mBuffers[portIndex].push(info);
5851065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            }
5861065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
5875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
5905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
5915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> notify = mNotify->dup();
594d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatBuffersAllocated);
5955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("portIndex", portIndex);
597eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
598eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    sp<PortDescription> desc = new PortDescription;
599eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
6005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
601eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        const BufferInfo &info = mBuffers[portIndex][i];
6025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
603eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        desc->addBuffer(info.mBufferID, info.mData);
604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
606eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    notify->setObject("portDesc", desc);
6075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->post();
6085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
612054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::configureOutputBuffersFromNativeWindow(
613054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 *bufferCount, OMX_U32 *bufferSize,
614054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 *minUndequeuedBuffers) {
615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = kPortIndexOutput;
618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffers_geometry(
627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameWidth,
629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameHeight,
630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.eColorFormat);
631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
63329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffers_geometry failed: %s (%d)",
634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                strerror(-err), -err);
635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
638e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang    if (mRotationDegrees != 0) {
639e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        uint32_t transform = 0;
640e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        switch (mRotationDegrees) {
641e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            case 0: transform = 0; break;
642e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            case 90: transform = HAL_TRANSFORM_ROT_90; break;
643e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            case 180: transform = HAL_TRANSFORM_ROT_180; break;
644e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            case 270: transform = HAL_TRANSFORM_ROT_270; break;
645e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            default: transform = 0; break;
646e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        }
647e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang
648e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        if (transform > 0) {
649e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            err = native_window_set_buffers_transform(
650e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang                    mNativeWindow.get(), transform);
651e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            if (err != 0) {
652e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang                ALOGE("native_window_set_buffers_transform failed: %s (%d)",
653e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang                        strerror(-err), -err);
654e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang                return err;
655e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            }
656e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        }
657e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang    }
658e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang
659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Set up the native window.
6603c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    OMX_U32 usage = 0;
6613c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
6623c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    if (err != 0) {
6635ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("querying usage flags from OMX IL component failed: %d", err);
6643c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        // XXX: Currently this error is logged, but not fatal.
6653c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        usage = 0;
6663c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    }
6673c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis
668bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (mFlags & kFlagIsSecure) {
669bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        usage |= GRALLOC_USAGE_PROTECTED;
670bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
671bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
672bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // Make sure to check whether either Stagefright or the video decoder
673bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // requested protected buffers.
674bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (usage & GRALLOC_USAGE_PROTECTED) {
675bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Verify that the ANativeWindow sends images directly to
676bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // SurfaceFlinger.
677bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        int queuesToNativeWindow = 0;
678bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->query(
679bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                mNativeWindow.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
680bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                &queuesToNativeWindow);
681bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != 0) {
682bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error authenticating native window: %d", err);
683bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
684bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
685bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (queuesToNativeWindow != 1) {
686bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("native window could not be authenticated");
687bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return PERMISSION_DENIED;
688bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
689bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
690bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_usage(
692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
6933c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis            usage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP);
694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
69629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err);
697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
700054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *minUndequeuedBuffers = 0;
701258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    err = mNativeWindow->query(
702258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
703054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (int *)minUndequeuedBuffers);
704258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
705258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    if (err != 0) {
70629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
707258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                strerror(-err), -err);
708258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        return err;
709258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
710258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
711e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // FIXME: assume that surface is controlled by app (native window
712e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // returns the number for the case when surface is not controlled by app)
7131faa41704e0b976e546321effcb09a85767d51baLajos Molnar    // FIXME2: This means that minUndeqeueudBufs can be 1 larger than reported
7141faa41704e0b976e546321effcb09a85767d51baLajos Molnar    // For now, try to allocate 1 more buffer, but don't fail if unsuccessful
715e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar
716e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // Use conservative allocation while also trying to reduce starvation
717e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //
718e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // 1. allocate at least nBufferCountMin + minUndequeuedBuffers - that is the
719e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //    minimum needed for the consumer to be able to work
720e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // 2. try to allocate two (2) additional buffers to reduce starvation from
721e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //    the consumer
7221faa41704e0b976e546321effcb09a85767d51baLajos Molnar    //    plus an extra buffer to account for incorrect minUndequeuedBufs
7231faa41704e0b976e546321effcb09a85767d51baLajos Molnar    for (OMX_U32 extraBuffers = 2 + 1; /* condition inside loop */; extraBuffers--) {
724e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        OMX_U32 newBufferCount =
725e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            def.nBufferCountMin + *minUndequeuedBuffers + extraBuffers;
726258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        def.nBufferCountActual = newBufferCount;
727258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        err = mOMX->setParameter(
728258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
729258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
730e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        if (err == OK) {
731e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            *minUndequeuedBuffers += extraBuffers;
732e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            break;
733e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        }
734e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar
735609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGW("[%s] setting nBufferCountActual to %u failed: %d",
736e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar                mComponentName.c_str(), newBufferCount, err);
737e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        /* exit condition */
738e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        if (extraBuffers == 0) {
739258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            return err;
740258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        }
741258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
742258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffer_count(
744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(), def.nBufferCountActual);
745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
74729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                -err);
749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
752054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferCount = def.nBufferCountActual;
753054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferSize =  def.nBufferSize;
754054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
755054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
756054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
757054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputBuffersFromNativeWindow() {
758054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
759054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
760054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
761054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
762054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
763e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    mNumUndequeuedBuffers = minUndequeuedBuffers;
764054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
765609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Allocating %u buffers from a native window of size %u on "
766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         "output port",
767054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount, bufferSize);
768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Dequeue buffers and send them to OMX
770054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
7718ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev        ANativeWindowBuffer *buf;
7721e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
77429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
775f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
77974006804065941841883c4b46ee785070164023fJamie Gennis        BufferInfo info;
78074006804065941841883c4b46ee785070164023fJamie Gennis        info.mStatus = BufferInfo::OWNED_BY_US;
781054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(NULL /* data */, bufferSize /* capacity */);
78274006804065941841883c4b46ee785070164023fJamie Gennis        info.mGraphicBuffer = graphicBuffer;
78374006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].push(info);
78474006804065941841883c4b46ee785070164023fJamie Gennis
785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferId;
786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &bufferId);
788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
789609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGE("registering GraphicBuffer %u with OMX IL component failed: "
79074006804065941841883c4b46ee785070164023fJamie Gennis                 "%d", i, err);
791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
79474006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
79574006804065941841883c4b46ee785070164023fJamie Gennis
796609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGV("[%s] Registered graphic buffer with ID %u (pointer = %p)",
797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mComponentName.c_str(),
798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             bufferId, graphicBuffer.get());
799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelStart;
802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelEnd;
803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // If an error occurred while dequeuing we need to cancel any buffers
806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // that were dequeued.
807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelStart = 0;
80874006804065941841883c4b46ee785070164023fJamie Gennis        cancelEnd = mBuffers[kPortIndexOutput].size();
809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
810054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // Return the required minimum undequeued buffers to the native window.
811054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelStart = bufferCount - minUndequeuedBuffers;
812054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelEnd = bufferCount;
813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
8173fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        status_t error = cancelBufferToNativeWindow(info);
8183fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        if (err == 0) {
8193fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia            err = error;
8203fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        }
821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
826054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputMetaDataBuffers() {
827054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
828054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
829054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
830054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
831054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
832e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    mNumUndequeuedBuffers = minUndequeuedBuffers;
833054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
834609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Allocating %u meta buffers on output port",
835054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount);
836054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
837054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    size_t totalSize = bufferCount * 8;
838054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mDealer[kPortIndexOutput] = new MemoryDealer(totalSize, "ACodec");
839054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
840054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // Dequeue buffers and send them to OMX
841054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
842054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo info;
843054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
844054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mGraphicBuffer = NULL;
845054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mDequeuedAt = mDequeueCounter;
846054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
847054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        sp<IMemory> mem = mDealer[kPortIndexOutput]->allocate(
848054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                sizeof(struct VideoDecoderOutputMetaData));
849054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(mem.get() != NULL);
850054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(mem->pointer(), mem->size());
851054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
852054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // we use useBuffer for metadata regardless of quirks
853054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        err = mOMX->useBuffer(
854054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mNode, kPortIndexOutput, mem, &info.mBufferID);
855054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
856054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        mBuffers[kPortIndexOutput].push(info);
857054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
858609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGV("[%s] allocated meta buffer with ID %u (pointer = %p)",
859054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mComponentName.c_str(), info.mBufferID, mem->pointer());
860054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
861054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
862054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mMetaDataBuffersToSubmit = bufferCount - minUndequeuedBuffers;
863054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
864054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
865054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
866054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::submitOutputMetaDataBuffer() {
867054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mStoreMetaDataInOutputBuffers);
868054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mMetaDataBuffersToSubmit == 0)
869054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return OK;
870054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
871054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *info = dequeueBufferFromNativeWindow();
872054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (info == NULL)
873054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return ERROR_IO;
874054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
875609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] submitting output meta buffer ID %u for graphic buffer %p",
876054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          mComponentName.c_str(), info->mBufferID, info->mGraphicBuffer.get());
877054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
878054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    --mMetaDataBuffersToSubmit;
879054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK_EQ(mOMX->fillBuffer(mNode, info->mBufferID),
880054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             (status_t)OK);
881054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
882054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
883054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return OK;
884054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
885054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
886f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
889609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Calling cancelBuffer on buffer %u",
890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mComponentName.c_str(), info->mBufferID);
891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int err = mNativeWindow->cancelBuffer(
8931e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        mNativeWindow.get(), info->mGraphicBuffer.get(), -1);
894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8953fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia    ALOGW_IF(err != 0, "[%s] can not return buffer %u to native window",
8963fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia            mComponentName.c_str(), info->mBufferID);
897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9003fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia    return err;
901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
903f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
9048ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev    ANativeWindowBuffer *buf;
9051e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    int fenceFd = -1;
906054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mNativeWindow.get() != NULL);
9071e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    if (native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf) != 0) {
90829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("dequeueBuffer failed.");
909c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber        return NULL;
910c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
912054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *oldest = NULL;
913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
917054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mGraphicBuffer != NULL &&
918054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            info->mGraphicBuffer->handle == buf->handle) {
919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus,
920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (int)BufferInfo::OWNED_BY_NATIVE_WINDOW);
921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
926054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
927054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW &&
928054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (oldest == NULL ||
929054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             // avoid potential issues from counter rolling over
930054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mDequeueCounter - info->mDequeuedAt >
931054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    mDequeueCounter - oldest->mDequeuedAt)) {
932054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            oldest = info;
933054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
934054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
935054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
936054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (oldest) {
937054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(mStoreMetaDataInOutputBuffers);
938054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
939054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // discard buffer in LRU info and replace with new buffer
940054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mGraphicBuffer = new GraphicBuffer(buf, false);
941054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mStatus = BufferInfo::OWNED_BY_US;
942054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
943d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        mOMX->updateGraphicBufferInMeta(
944d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                mNode, kPortIndexOutput, oldest->mGraphicBuffer,
945d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                oldest->mBufferID);
946054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
947d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        VideoDecoderOutputMetaData *metaData =
948d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar            reinterpret_cast<VideoDecoderOutputMetaData *>(
949d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                    oldest->mData->base());
950d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        CHECK_EQ(metaData->eType, kMetadataBufferTypeGrallocSource);
951d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar
952d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
953054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                oldest - &mBuffers[kPortIndexOutput][0],
954054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mDequeueCounter - oldest->mDequeuedAt,
955d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                metaData->pHandle,
956d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                oldest->mGraphicBuffer->handle, oldest->mData->base());
957054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
958054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return oldest;
959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
966f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[portIndex].size(); i-- > 0;) {
968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, freeBuffer(portIndex, i));
969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDealer[portIndex].clear();
972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
976349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huberstatus_t ACodec::freeOutputBuffersNotOwnedByComponent() {
977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9812ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // At this time some buffers may still be with the component
9822ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // or being drained.
9832ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT &&
9842ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar            info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) {
985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK, freeBuffer(kPortIndexOutput, i));
986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
992f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(info->mStatus == BufferInfo::OWNED_BY_US
996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput && mNativeWindow != NULL
999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && info->mStatus == BufferInfo::OWNED_BY_US) {
10003fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        cancelBufferToNativeWindow(info);
1001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(mOMX->freeBuffer(
1004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, portIndex, info->mBufferID),
1005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
1006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mBuffers[portIndex].removeAt(i);
1008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1012f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::findBufferByID(
1013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        uint32_t portIndex, IOMX::buffer_id bufferID,
1014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ssize_t *index) {
1015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
1016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
1017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mBufferID == bufferID) {
1019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (index != NULL) {
1020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                *index = i;
1021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
1023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
1027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
1029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10315778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setComponentRole(
1032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        bool isEncoder, const char *mime) {
1033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    struct MimeToRole {
1034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime;
1035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *decoderRole;
1036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *encoderRole;
1037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
1038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const MimeToRole kMimeToRole[] = {
1040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG,
1041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.mp3", "audio_encoder.mp3" },
10422944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
10432944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp1", "audio_encoder.mp1" },
10442944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
10452944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp2", "audio_encoder.mp2" },
1046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_NB,
1047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrnb", "audio_encoder.amrnb" },
1048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_WB,
1049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrwb", "audio_encoder.amrwb" },
1050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AAC,
1051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.aac", "audio_encoder.aac" },
1052729de186450f78c099637e1fce743fe531862c52Andreas Huber        { MEDIA_MIMETYPE_AUDIO_VORBIS,
1053729de186450f78c099637e1fce743fe531862c52Andreas Huber            "audio_decoder.vorbis", "audio_encoder.vorbis" },
1054bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian        { MEDIA_MIMETYPE_AUDIO_OPUS,
1055bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian            "audio_decoder.opus", "audio_encoder.opus" },
1056c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_MLAW,
1057c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" },
1058c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_ALAW,
1059c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711alaw", "audio_encoder.g711alaw" },
1060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_AVC,
1061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.avc", "video_encoder.avc" },
10622472b1c0d63454e5d90a982bd6c555de6c3127bdRachad        { MEDIA_MIMETYPE_VIDEO_HEVC,
10632472b1c0d63454e5d90a982bd6c555de6c3127bdRachad            "video_decoder.hevc", "video_encoder.hevc" },
1064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_MPEG4,
1065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.mpeg4", "video_encoder.mpeg4" },
1066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_H263,
1067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.h263", "video_encoder.h263" },
106894705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP8,
106994705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp8", "video_encoder.vp8" },
107094705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP9,
107194705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp9", "video_encoder.vp9" },
1072ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        { MEDIA_MIMETYPE_AUDIO_RAW,
1073ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            "audio_decoder.raw", "audio_encoder.raw" },
10742f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        { MEDIA_MIMETYPE_AUDIO_FLAC,
10752f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            "audio_decoder.flac", "audio_encoder.flac" },
1076ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        { MEDIA_MIMETYPE_AUDIO_MSGSM,
1077ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen            "audio_decoder.gsm", "audio_encoder.gsm" },
1078774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu        { MEDIA_MIMETYPE_VIDEO_MPEG2,
1079774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu            "video_decoder.mpeg2", "video_encoder.mpeg2" },
108097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        { MEDIA_MIMETYPE_AUDIO_AC3,
108197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            "audio_decoder.ac3", "audio_encoder.ac3" },
1082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
1083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const size_t kNumMimeToRole =
1085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
1086f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    size_t i;
1088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (i = 0; i < kNumMimeToRole; ++i) {
1089f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcasecmp(mime, kMimeToRole[i].mime)) {
1090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1094f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (i == kNumMimeToRole) {
10955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_UNSUPPORTED;
1096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    const char *role =
1099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        isEncoder ? kMimeToRole[i].encoderRole
1100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                  : kMimeToRole[i].decoderRole;
1101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (role != NULL) {
1103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_PARAM_COMPONENTROLETYPE roleParams;
1104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        InitOMXParams(&roleParams);
1105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        strncpy((char *)roleParams.cRole,
1107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                role, OMX_MAX_STRINGNAME_SIZE - 1);
1108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
1110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->setParameter(
1112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamStandardComponentRole,
1113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &roleParams, sizeof(roleParams));
1114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
11165ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("[%s] Failed to set standard component role '%s'.",
1117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 mComponentName.c_str(), role);
11185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
1120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
11225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
1124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
11265778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::configureCodec(
1127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime, const sp<AMessage> &msg) {
11285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t encoder;
11295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("encoder", &encoder)) {
11305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        encoder = false;
11315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1133e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    sp<AMessage> inputFormat = new AMessage();
1134e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    sp<AMessage> outputFormat = new AMessage();
1135e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
11365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mIsEncoder = encoder;
1137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
11385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setComponentRole(encoder /* isEncoder */, mime);
11395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
11415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
11425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
11435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitRate = 0;
11452f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    // FLAC encoder doesn't need a bitrate, other encoders do
11462f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
11472f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            && !msg->findInt32("bitrate", &bitRate)) {
11485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
11495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
11505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1151d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    int32_t storeMeta;
1152d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (encoder
1153d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && msg->findInt32("store-metadata-in-buffers", &storeMeta)
1154d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && storeMeta != 0) {
1155d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE);
1156d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1157d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (err != OK) {
1158308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              ALOGE("[%s] storeMetaDataInBuffers (input) failed w/ err %d",
1159308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    mComponentName.c_str(), err);
1160d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1161308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              return err;
1162308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang          }
1163308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang      }
1164d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1165308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t prependSPSPPS = 0;
11663a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    if (encoder
11673a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
11683a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && prependSPSPPS != 0) {
11693a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        OMX_INDEXTYPE index;
11703a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        err = mOMX->getExtensionIndex(
11713a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                mNode,
11723a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                "OMX.google.android.index.prependSPSPPSToIDRFrames",
11733a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                &index);
11743a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
11753a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err == OK) {
11763a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            PrependSPSPPSToIDRFramesParams params;
11773a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            InitOMXParams(&params);
11783a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            params.bEnable = OMX_TRUE;
11793a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
11803a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            err = mOMX->setParameter(
11813a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                    mNode, index, &params, sizeof(params));
11823a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
11833a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
11843a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err != OK) {
11853a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            ALOGE("Encoder could not be configured to emit SPS/PPS before "
11863a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                  "IDR frames. (err %d)", err);
11873a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
11883a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            return err;
11893a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
11903a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    }
11913a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
1192308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // Only enable metadata mode on encoder output if encoder can prepend
1193308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // sps/pps to idr frames, since in metadata mode the bitstream is in an
1194308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // opaque handle, to which we don't have access.
1195308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t video = !strncasecmp(mime, "video/", 6);
1196308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (encoder && video) {
1197308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS
1198308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && msg->findInt32("store-metadata-in-buffers-output", &storeMeta)
1199308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && storeMeta != 0);
1200308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1201308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, enable);
1202308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1203308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        if (err != OK) {
1204308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            ALOGE("[%s] storeMetaDataInBuffers (output) failed w/ err %d",
1205308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                mComponentName.c_str(), err);
1206308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = 0;
1207308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        } else {
1208308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = enable;
1209308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        }
1210a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
1211a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (!msg->findInt64(
1212a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    "repeat-previous-frame-after",
1213a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    &mRepeatFrameDelayUs)) {
1214a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            mRepeatFrameDelayUs = -1ll;
1215a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
121694ee4b708acfa941581160b267afb79192b1d816Chong Zhang
121794ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (!msg->findInt64("max-pts-gap-to-encoder", &mMaxPtsGapUs)) {
12182c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mMaxPtsGapUs = -1ll;
12192c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
12202c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
12212c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (!msg->findInt64("time-lapse", &mTimePerCaptureUs)) {
12222c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mTimePerCaptureUs = -1ll;
122394ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
122472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
122572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (!msg->findInt32(
122672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    "create-input-buffers-suspended",
122772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    (int32_t*)&mCreateInputBuffersSuspended)) {
122872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mCreateInputBuffersSuspended = false;
122972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
1230308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    }
1231308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1232054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    sp<RefBase> obj;
1233054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    int32_t haveNativeWindow = msg->findObject("native-window", &obj) &&
12345a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        obj != NULL;
1235054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mStoreMetaDataInOutputBuffers = false;
1236e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if (video && !encoder) {
1237e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        inputFormat->setInt32("adaptive-playback", false);
1238e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
1239054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (!encoder && video && haveNativeWindow) {
12405a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        sp<NativeWindowWrapper> windowWrapper(
12415a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                static_cast<NativeWindowWrapper *>(obj.get()));
12425a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        sp<ANativeWindow> nativeWindow = windowWrapper->getNativeWindow();
12435a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
12445a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        int32_t tunneled;
12455a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        if (msg->findInt32("feature-tunneled-playback", &tunneled) &&
12465a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            tunneled != 0) {
12475a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            ALOGI("Configuring TUNNELED video playback.");
12485a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
124997827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad            int32_t audioHwSync = 0;
125097827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad            if (!msg->findInt32("audio-hw-sync", &audioHwSync)) {
12515a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGW("No Audio HW Sync provided for video tunnel");
12525a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            }
12535a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            err = configureTunneledVideoPlayback(audioHwSync, nativeWindow);
12545a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (err != OK) {
125597827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad                ALOGE("configureTunneledVideoPlayback(%d,%p) failed!",
12565a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        audioHwSync, nativeWindow.get());
12575a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                return err;
1258fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
1259fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
12605a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            inputFormat->setInt32("adaptive-playback", true);
12615a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        } else {
12625a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            // Always try to enable dynamic output buffers on native surface
12635a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            err = mOMX->storeMetaDataInBuffers(
12645a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    mNode, kPortIndexOutput, OMX_TRUE);
12655a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (err != OK) {
12665a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d",
1267fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        mComponentName.c_str(), err);
1268e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
12695a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // if adaptive playback has been requested, try JB fallback
12705a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // NOTE: THIS FALLBACK MECHANISM WILL BE REMOVED DUE TO ITS
12715a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // LARGE MEMORY REQUIREMENT
12725a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
12735a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // we will not do adaptive playback on software accessed
12745a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // surfaces as they never had to respond to changes in the
12755a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // crop window, and we don't trust that they will be able to.
12765a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                int usageBits = 0;
12775a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                bool canDoAdaptivePlayback;
12785a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
12795a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                if (nativeWindow->query(
12805a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        nativeWindow.get(),
12815a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        NATIVE_WINDOW_CONSUMER_USAGE_BITS,
12825a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        &usageBits) != OK) {
12835a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    canDoAdaptivePlayback = false;
12845a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                } else {
12855a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    canDoAdaptivePlayback =
12865a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        (usageBits &
12875a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                                (GRALLOC_USAGE_SW_READ_MASK |
12885a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                                 GRALLOC_USAGE_SW_WRITE_MASK)) == 0;
12895a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                }
12905a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
12915a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                int32_t maxWidth = 0, maxHeight = 0;
12925a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                if (canDoAdaptivePlayback &&
12935a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        msg->findInt32("max-width", &maxWidth) &&
12945a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        msg->findInt32("max-height", &maxHeight)) {
12955a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    ALOGV("[%s] prepareForAdaptivePlayback(%dx%d)",
12965a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mComponentName.c_str(), maxWidth, maxHeight);
12975a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
12985a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    err = mOMX->prepareForAdaptivePlayback(
12995a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mNode, kPortIndexOutput, OMX_TRUE, maxWidth,
13005a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            maxHeight);
13015a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    ALOGW_IF(err != OK,
13025a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            "[%s] prepareForAdaptivePlayback failed w/ err %d",
13035a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mComponentName.c_str(), err);
13045a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
13055a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    if (err == OK) {
13065a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("max-width", maxWidth);
13075a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("max-height", maxHeight);
13085a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("adaptive-playback", true);
13095a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    }
1310e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
13115a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // allow failure
13125a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                err = OK;
13135a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            } else {
13145a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGV("[%s] storeMetaDataInBuffers succeeded",
13155a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        mComponentName.c_str());
13165a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                mStoreMetaDataInOutputBuffers = true;
13175a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                inputFormat->setInt32("adaptive-playback", true);
1318fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
13190167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber
13205a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            int32_t push;
13215a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (msg->findInt32("push-blank-buffers-on-shutdown", &push)
13225a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    && push != 0) {
13235a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
13245a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            }
13250167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        }
1326e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang
1327e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        int32_t rotationDegrees;
1328e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        if (msg->findInt32("rotation-degrees", &rotationDegrees)) {
1329e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            mRotationDegrees = rotationDegrees;
1330e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        } else {
1331e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            mRotationDegrees = 0;
1332e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        }
1333054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1334054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1335308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (video) {
13365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (encoder) {
13375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupVideoEncoder(mime, msg);
13385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
133989869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            err = setupVideoDecoder(mime, msg);
13405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
134142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
134242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        int32_t numChannels, sampleRate;
134342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        if (!msg->findInt32("channel-count", &numChannels)
134442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
134542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // Since we did not always check for these, leave them optional
134642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // and have the decoder figure it all out.
134742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = OK;
134842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        } else {
134942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = setupRawAudioFormat(
135042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    encoder ? kPortIndexInput : kPortIndexOutput,
135142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    sampleRate,
135242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    numChannels);
135342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        }
1354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
1355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t numChannels, sampleRate;
13565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)
13575778822d86b0337407514b9372562b86edfa91cdAndreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
13585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
13595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
1360aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            int32_t isADTS, aacProfile;
1361b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            int32_t sbrMode;
13628045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            int32_t maxOutputChannelCount;
13632965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            int32_t pcmLimiterEnable;
13648045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            drcParams_t drc;
1365ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            if (!msg->findInt32("is-adts", &isADTS)) {
1366ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                isADTS = 0;
1367ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
1368aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (!msg->findInt32("aac-profile", &aacProfile)) {
1369aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                aacProfile = OMX_AUDIO_AACObjectNull;
1370aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
1371b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            if (!msg->findInt32("aac-sbr-mode", &sbrMode)) {
1372b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                sbrMode = -1;
1373b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            }
1374ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
13758045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-max-output-channel_count", &maxOutputChannelCount)) {
13768045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                maxOutputChannelCount = -1;
13778045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
13782965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            if (!msg->findInt32("aac-pcm-limiter-enable", &pcmLimiterEnable)) {
13792965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                // value is unknown
13802965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                pcmLimiterEnable = -1;
13812965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            }
13828045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-encoded-target-level", &drc.encodedTargetLevel)) {
13838045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
13848045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.encodedTargetLevel = -1;
13858045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
13868045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-cut-level", &drc.drcCut)) {
13878045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
13888045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.drcCut = -1;
13898045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
13908045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-boost-level", &drc.drcBoost)) {
13918045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
13928045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.drcBoost = -1;
13938045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
13948045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-heavy-compression", &drc.heavyCompression)) {
13958045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
13968045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.heavyCompression = -1;
13978045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
13988045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-target-ref-level", &drc.targetRefLevel)) {
13998045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
14008045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.targetRefLevel = -1;
14018045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
14028045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi
1403ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            err = setupAACCodec(
14044471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    encoder, numChannels, sampleRate, bitRate, aacProfile,
14052965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                    isADTS != 0, sbrMode, maxOutputChannelCount, drc,
14062965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                    pcmLimiterEnable);
14075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
1408729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
14095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
1410729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
14115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
1412729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
1413729de186450f78c099637e1fce743fe531862c52Andreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
1414729de186450f78c099637e1fce743fe531862c52Andreas Huber        // These are PCM-like formats with a fixed sample rate but
1415729de186450f78c099637e1fce743fe531862c52Andreas Huber        // a variable number of channels.
1416729de186450f78c099637e1fce743fe531862c52Andreas Huber
1417729de186450f78c099637e1fce743fe531862c52Andreas Huber        int32_t numChannels;
14185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)) {
14195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
14205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
14215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupG711Codec(encoder, numChannels);
14225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14232f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
14242f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        int32_t numChannels, sampleRate, compressionLevel = -1;
14252f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (encoder &&
14262f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                (!msg->findInt32("channel-count", &numChannels)
14272f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                        || !msg->findInt32("sample-rate", &sampleRate))) {
14282f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("missing channel count or sample rate for FLAC encoder");
14292f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            err = INVALID_OPERATION;
14302f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        } else {
14312f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            if (encoder) {
1432516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                if (!msg->findInt32(
1433cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                            "complexity", &compressionLevel) &&
1434cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                    !msg->findInt32(
1435516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                            "flac-compression-level", &compressionLevel)) {
1436cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                    compressionLevel = 5; // default FLAC compression level
14372f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel < 0) {
1438516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1439516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 0",
1440516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
14412f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 0;
14422f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel > 8) {
1443516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1444516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 8",
1445516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
14462f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 8;
14472f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                }
14482f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            }
1449516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            err = setupFlacCodec(
1450516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    encoder, numChannels, sampleRate, compressionLevel);
14512f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
1452ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
1453ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        int32_t numChannels, sampleRate;
1454ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        if (encoder
1455ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("channel-count", &numChannels)
1456ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
1457ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = INVALID_OPERATION;
1458ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        } else {
1459ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
1460ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        }
146197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AC3)) {
146297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t numChannels;
146397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t sampleRate;
146497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        if (!msg->findInt32("channel-count", &numChannels)
146597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                || !msg->findInt32("sample-rate", &sampleRate)) {
146697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = INVALID_OPERATION;
146797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        } else {
146897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = setupAC3Codec(encoder, numChannels, sampleRate);
146997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        }
14705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1471729de186450f78c099637e1fce743fe531862c52Andreas Huber
14724471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    if (err != OK) {
14734471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber        return err;
14744471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    }
14754471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber
14768b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
14778b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderDelay = 0;
14788b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
14799806555d3930be43e11106281dee354820ac1c88Andreas Huber
14808b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
14818b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderPadding = 0;
14828b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
14838b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen
14849806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (msg->findInt32("channel-mask", &mChannelMask)) {
14859806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = true;
14869806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else {
14879806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = false;
14889806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
14899806555d3930be43e11106281dee354820ac1c88Andreas Huber
1490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t maxInputSize;
1491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (msg->findInt32("max-input-size", &maxInputSize)) {
14925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
1493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
14945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
1495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
14965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1497e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ(getPortFormat(kPortIndexInput, inputFormat), (status_t)OK);
1498e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ(getPortFormat(kPortIndexOutput, outputFormat), (status_t)OK);
1499e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mInputFormat = inputFormat;
1500e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mOutputFormat = outputFormat;
1501e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
15025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
1503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1505f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
1506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
1508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
1509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (def.nBufferSize >= size) {
1518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
1519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nBufferSize = size;
1522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
1524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->getParameter(
1531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(def.nBufferSize >= size);
1538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
15425778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::selectAudioPortFormat(
15435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
15445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_AUDIO_PARAM_PORTFORMATTYPE format;
15455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&format);
15465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    format.nPortIndex = portIndex;
15485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (OMX_U32 index = 0;; ++index) {
15495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        format.nIndex = index;
15505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
15525778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioPortFormat,
15535778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &format, sizeof(format));
15545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
15565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
15575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (format.eEncoding == desiredFormat) {
15605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
15615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
15655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format));
15665778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
15675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15685778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAACCodec(
1569aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        bool encoder, int32_t numChannels, int32_t sampleRate,
15708045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        int32_t bitRate, int32_t aacProfile, bool isADTS, int32_t sbrMode,
15712965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang        int32_t maxOutputChannelCount, const drcParams_t& drc,
15722965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang        int32_t pcmLimiterEnable) {
1573ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (encoder && isADTS) {
1574ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return -EINVAL;
1575ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
1576ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
15775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setupRawAudioFormat(
15785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
15795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sampleRate,
15805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            numChannels);
15815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
15835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
15845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (encoder) {
15875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
15885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
15905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
15915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
15945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
15955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = kPortIndexOutput;
15965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
15985778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
15995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
16015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
16025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.bFlagErrorConcealment = OMX_TRUE;
16055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
16065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
16085778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
16095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
16115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
16125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
16155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&profile);
16165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nPortIndex = kPortIndexOutput;
16175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
16195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
16205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
16225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
16235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nChannels = numChannels;
16265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eChannelMode =
16285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (numChannels == 1)
16295778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
16305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nSampleRate = sampleRate;
16325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nBitRate = bitRate;
16335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAudioBandWidth = 0;
16345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nFrameLength = 0;
16355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACtools = OMX_AUDIO_AACToolAll;
16365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACERtools = OMX_AUDIO_AACERNone;
1637aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
16385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
1639b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        switch (sbrMode) {
1640b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 0:
1641b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // disable sbr
1642b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
1643b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
1644b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
1645b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 1:
1646b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable single-rate sbr
1647b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
1648b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
1649b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
1650b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 2:
1651b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable dual-rate sbr
1652b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
1653b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
1654b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
1655b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case -1:
1656b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable both modes -> the codec will decide which mode should be used
1657b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
1658b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
1659b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
1660b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        default:
1661b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // unsupported sbr mode
1662b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            return BAD_VALUE;
1663b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        }
1664b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi
16655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
16675778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
16685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
16705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
16715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
16745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_AUDIO_PARAM_AACPROFILETYPE profile;
1677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&profile);
1678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nPortIndex = kPortIndexInput;
1679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
16805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
1681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
1682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nChannels = numChannels;
1688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nSampleRate = sampleRate;
1689ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1690ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    profile.eAACStreamFormat =
1691ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        isADTS
1692ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            ? OMX_AUDIO_AACStreamFormatMP4ADTS
1693ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            : OMX_AUDIO_AACStreamFormatMP4FF;
1694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
16958045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    OMX_AUDIO_PARAM_ANDROID_AACPRESENTATIONTYPE presentation;
16968045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nMaxOutputChannels = maxOutputChannelCount;
16978045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nDrcCut = drc.drcCut;
16988045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nDrcBoost = drc.drcBoost;
16998045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nHeavyCompression = drc.heavyCompression;
17008045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nTargetReferenceLevel = drc.targetRefLevel;
17018045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nEncodedTargetLevel = drc.encodedTargetLevel;
17022965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang    presentation.nPCMLimiterEnable = pcmLimiterEnable;
17038045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi
17048045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    status_t res = mOMX->setParameter(mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
17058045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    if (res == OK) {
17068045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        // optional parameters, will not cause configuration failure
17078045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        mOMX->setParameter(mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAacPresentation,
17088045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                &presentation, sizeof(presentation));
17098045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    } else {
17108045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        ALOGW("did not set AudioAndroidAacPresentation due to error %d when setting AudioAac", res);
17118045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    }
17128045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    return res;
17135778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
171597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryustatus_t ACodec::setupAC3Codec(
171697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        bool encoder, int32_t numChannels, int32_t sampleRate) {
171797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    status_t err = setupRawAudioFormat(
171897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
171997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
172097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
172197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
172297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
172397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
172497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (encoder) {
172597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        ALOGW("AC3 encoding is not supported.");
172697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return INVALID_OPERATION;
172797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
172897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
172997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    OMX_AUDIO_PARAM_ANDROID_AC3TYPE def;
173097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    InitOMXParams(&def);
173197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nPortIndex = kPortIndexInput;
173297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
173397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    err = mOMX->getParameter(
173497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
173597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
173697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
173797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
173897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
173997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
174097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
174197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
174297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
174397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nChannels = numChannels;
174497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nSampleRate = sampleRate;
174597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
174697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    return mOMX->setParameter(
174797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
174897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
174997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
175097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
175197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu}
175297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
17535778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
17545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        bool isAMRWB, int32_t bps) {
17555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (isAMRWB) {
17565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 6600) {
17575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB0;
17585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 8850) {
17595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB1;
17605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 12650) {
17615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB2;
17625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 14250) {
17635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB3;
17645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 15850) {
17655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB4;
17665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 18250) {
17675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB5;
17685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 19850) {
17695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB6;
17705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 23050) {
17715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB7;
17725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 23850 bps
17755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeWB8;
17765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {  // AMRNB
17775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 4750) {
17785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB0;
17795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5150) {
17805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB1;
17815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5900) {
17825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB2;
17835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 6700) {
17845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB3;
17855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7400) {
17865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB4;
17875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7950) {
17885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB5;
17895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 10200) {
17905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB6;
17915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 12200 bps
17945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeNB7;
17955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
17985778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
1799729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_AMRTYPE def;
1800729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
18015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
1802729de186450f78c099637e1fce743fe531862c52Andreas Huber
1803729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err =
1804729de186450f78c099637e1fce743fe531862c52Andreas Huber        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1805729de186450f78c099637e1fce743fe531862c52Andreas Huber
1806729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1807729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1808729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1809729de186450f78c099637e1fce743fe531862c52Andreas Huber
1810729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
18115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
18125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
18145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1815729de186450f78c099637e1fce743fe531862c52Andreas Huber
18165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1819729de186450f78c099637e1fce743fe531862c52Andreas Huber
18205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupRawAudioFormat(
18215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
18225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            isWAMR ? 16000 : 8000 /* sampleRate */,
18235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            1 /* numChannels */);
1824729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1825729de186450f78c099637e1fce743fe531862c52Andreas Huber
18265778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupG711Codec(bool encoder, int32_t numChannels) {
18275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(!encoder);  // XXX TODO
18285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1829729de186450f78c099637e1fce743fe531862c52Andreas Huber    return setupRawAudioFormat(
1830729de186450f78c099637e1fce743fe531862c52Andreas Huber            kPortIndexInput, 8000 /* sampleRate */, numChannels);
1831729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1832729de186450f78c099637e1fce743fe531862c52Andreas Huber
18332f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivistatus_t ACodec::setupFlacCodec(
18342f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
18352f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
18362f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder) {
18372f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        OMX_AUDIO_PARAM_FLACTYPE def;
18382f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        InitOMXParams(&def);
18392f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nPortIndex = kPortIndexOutput;
18402f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
18412f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        // configure compression level
18422f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        status_t err = mOMX->getParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
18432f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
18442f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
18452f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
18462f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
18472f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nCompressionLevel = compressionLevel;
18482f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        err = mOMX->setParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
18492f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
18502f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
18512f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
18522f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
18532f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
18542f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
18552f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    return setupRawAudioFormat(
18562f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            encoder ? kPortIndexInput : kPortIndexOutput,
18572f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            sampleRate,
18582f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            numChannels);
18592f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi}
18602f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
1861729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t ACodec::setupRawAudioFormat(
1862729de186450f78c099637e1fce743fe531862c52Andreas Huber        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
1863729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1864729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
1865729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.nPortIndex = portIndex;
1866729de186450f78c099637e1fce743fe531862c52Andreas Huber
1867729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err = mOMX->getParameter(
1868729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1869729de186450f78c099637e1fce743fe531862c52Andreas Huber
1870729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1871729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1872729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1873729de186450f78c099637e1fce743fe531862c52Andreas Huber
1874729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
1875729de186450f78c099637e1fce743fe531862c52Andreas Huber
1876729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->setParameter(
1877729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1878729de186450f78c099637e1fce743fe531862c52Andreas Huber
1879729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1880729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1881729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1882729de186450f78c099637e1fce743fe531862c52Andreas Huber
1883729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
1884729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&pcmParams);
1885729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nPortIndex = portIndex;
1886729de186450f78c099637e1fce743fe531862c52Andreas Huber
1887729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->getParameter(
1888729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1889729de186450f78c099637e1fce743fe531862c52Andreas Huber
1890729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1891729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1892729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1893729de186450f78c099637e1fce743fe531862c52Andreas Huber
1894729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nChannels = numChannels;
1895729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.eNumData = OMX_NumericalDataSigned;
1896729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.bInterleaved = OMX_TRUE;
1897729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nBitPerSample = 16;
1898729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nSamplingRate = sampleRate;
1899729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
1900729de186450f78c099637e1fce743fe531862c52Andreas Huber
1901c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber    if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
1902c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber        return OMX_ErrorNone;
1903729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1904729de186450f78c099637e1fce743fe531862c52Andreas Huber
1905729de186450f78c099637e1fce743fe531862c52Andreas Huber    return mOMX->setParameter(
1906729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1907729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1908729de186450f78c099637e1fce743fe531862c52Andreas Huber
19095a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachadstatus_t ACodec::configureTunneledVideoPlayback(
191097827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad        int32_t audioHwSync, const sp<ANativeWindow> &nativeWindow) {
19115a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    native_handle_t* sidebandHandle;
19125a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
19135a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    status_t err = mOMX->configureVideoTunnelMode(
19145a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            mNode, kPortIndexOutput, OMX_TRUE, audioHwSync, &sidebandHandle);
19155a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    if (err != OK) {
19165a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        ALOGE("configureVideoTunnelMode failed! (err %d).", err);
19175a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        return err;
19185a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    }
19195a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
19205a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    err = native_window_set_sideband_stream(nativeWindow.get(), sidebandHandle);
19215a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    if (err != OK) {
19225a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        ALOGE("native_window_set_sideband_stream(%p) failed! (err %d).",
19235a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                sidebandHandle, err);
19245a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        return err;
19255a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    }
19265a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
19275a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    return OK;
19285a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad}
19295a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
1930f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoPortFormatType(
1931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
1932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_VIDEO_CODINGTYPE compressionFormat,
1933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_COLOR_FORMATTYPE colorFormat) {
1934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
1936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = portIndex;
1937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
1938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool found = false;
1939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 index = 0;
1941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (;;) {
1942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        format.nIndex = index;
1943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->getParameter(
1944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamVideoPortFormat,
1945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &format, sizeof(format));
1946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
1948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return err;
1949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1951229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        // substitute back flexible color format to codec supported format
1952229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        OMX_U32 flexibleEquivalent;
1953229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        if (compressionFormat == OMX_VIDEO_CodingUnused &&
1954229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                isFlexibleColorFormat(
1955229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                        mOMX, mNode, format.eColorFormat, &flexibleEquivalent) &&
1956229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                colorFormat == flexibleEquivalent) {
1957229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            ALOGI("[%s] using color format %#x in place of %#x",
1958229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                    mComponentName.c_str(), format.eColorFormat, colorFormat);
1959229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            colorFormat = format.eColorFormat;
1960229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
1961229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
1962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The following assertion is violated by TI's video decoder.
1963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // CHECK_EQ(format.nIndex, index);
1964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
1966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexInput
1967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && colorFormat == format.eColorFormat) {
1968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eCompressionFormat does not seem right.
1969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
1970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
1971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexOutput
1973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && compressionFormat == format.eCompressionFormat) {
1974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eColorFormat does not seem right.
1975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
1976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
1977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (format.eCompressionFormat == compressionFormat
1981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && format.eColorFormat == colorFormat) {
1982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            found = true;
1983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ++index;
1987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!found) {
1990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return UNKNOWN_ERROR;
1991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->setParameter(
1994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
1998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2000f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setSupportedOutputFormat() {
2001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
2002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
2003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = kPortIndexOutput;
2004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
2005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
2007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
2008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
2009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
2010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)format.eCompressionFormat, (int)OMX_VIDEO_CodingUnused);
2011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mOMX->setParameter(
2013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
2014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
2015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2017e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic const struct VideoCodingMapEntry {
2018e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    const char *mMime;
2019e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    OMX_VIDEO_CODINGTYPE mVideoCodingType;
2020e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber} kVideoCodingMapEntry[] = {
2021e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC },
20222472b1c0d63454e5d90a982bd6c555de6c3127bdRachad    { MEDIA_MIMETYPE_VIDEO_HEVC, OMX_VIDEO_CodingHEVC },
2023e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 },
2024e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 },
2025e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 },
202694705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 },
202794705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 },
2028e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber};
2029e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
20305778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic status_t GetVideoCodingTypeFromMime(
20315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
2032e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
2033e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
2034e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
2035e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) {
2036e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *codingType = kVideoCodingMapEntry[i].mVideoCodingType;
2037e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
2038e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
2039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2041e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    *codingType = OMX_VIDEO_CodingUnused;
2042e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2043e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
2044e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
2045e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2046e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic status_t GetMimeTypeForVideoCoding(
2047e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        OMX_VIDEO_CODINGTYPE codingType, AString *mime) {
2048e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
2049e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
2050e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
2051e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) {
2052e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *mime = kVideoCodingMapEntry[i].mMime;
2053e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
2054e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
2055e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
2056e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2057e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    mime->clear();
2058e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2059e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
20605778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
20615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20625778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoDecoder(
206389869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        const char *mime, const sp<AMessage> &msg) {
206489869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    int32_t width, height;
206589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    if (!msg->findInt32("width", &width)
206689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            || !msg->findInt32("height", &height)) {
206789869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        return INVALID_OPERATION;
206889869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    }
206989869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar
20705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
20715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
20725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
2078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
2079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2081f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
208489869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    int32_t tmp;
208589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    if (msg->findInt32("color-format", &tmp)) {
208689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        OMX_COLOR_FORMATTYPE colorFormat =
208789869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            static_cast<OMX_COLOR_FORMATTYPE>(tmp);
208889869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        err = setVideoPortFormatType(
208989869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar                kPortIndexOutput, OMX_VIDEO_CodingUnused, colorFormat);
209089869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        if (err != OK) {
209189869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            ALOGW("[%s] does not support color format %d",
209289869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar                  mComponentName.c_str(), colorFormat);
209389869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            err = setSupportedOutputFormat();
209489869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        }
209589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    } else {
209689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        err = setSupportedOutputFormat();
209789869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    }
2098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
2104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, width, height, compressionFormat);
2105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
2111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
2112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
21205778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) {
21215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
21225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("color-format", &tmp)) {
21235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
21245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_COLOR_FORMATTYPE colorFormat =
21275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        static_cast<OMX_COLOR_FORMATTYPE>(tmp);
21285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setVideoPortFormatType(
21305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
21315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support color format %d",
21345778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str(), colorFormat);
21355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Input port configuration */
21405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
21425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&def);
21435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
21455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexInput;
21475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
21495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
21505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t width, height, bitrate;
21565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("width", &width)
21575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("height", &height)
21585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("bitrate", &bitrate)) {
21595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
21605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
21635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
21645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t stride;
21665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("stride", &stride)) {
21675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        stride = width;
21685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nStride = stride;
21715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t sliceHeight;
21735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("slice-height", &sliceHeight)) {
21745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sliceHeight = height;
21755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nSliceHeight = sliceHeight;
21785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
21805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
21825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
21835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
21845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
21855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
21865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
21882c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        mTimePerFrameUs = (int64_t) (1000000.0f / frameRate);
21895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
21925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
21935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = colorFormat;
21945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
21965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
21975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set input port definition parameters.",
22005778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
22015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Output port configuration */
22065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
22085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
22095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
22155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
22165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support compression format %d",
22195778822d86b0337407514b9372562b86edfa91cdAndreas Huber             mComponentName.c_str(), compressionFormat);
22205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexOutput;
22255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
22275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
22285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
22345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
22355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = 0;
22365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nBitrate = bitrate;
22375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = compressionFormat;
22385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = OMX_COLOR_FormatUnused;
22395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
22415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
22425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set output port definition parameters.",
22455778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
22465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (compressionFormat) {
22515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingMPEG4:
22525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupMPEG4EncoderParameters(msg);
22535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
22545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingH263:
22565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupH263EncoderParameters(msg);
22575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
22585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingAVC:
22605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupAVCEncoderParameters(msg);
22615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
22625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2263c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        case OMX_VIDEO_CodingHEVC:
2264c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            err = setupHEVCEncoderParameters(msg);
2265c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            break;
2266c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
226789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP8:
226889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP9:
226989b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            err = setupVPXEncoderParameters(msg);
227089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            break;
227189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
22725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
22735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
22745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGI("setupVideoEncoder succeeded");
22775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
22795778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
22805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22810dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dongstatus_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) {
22820dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    OMX_VIDEO_PARAM_INTRAREFRESHTYPE params;
22830dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    InitOMXParams(&params);
22840dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.nPortIndex = kPortIndexOutput;
22850dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
22860dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode);
22870dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
22880dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic ||
22890dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
22900dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
22910dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) {
22920dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
22930dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
22940dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nCirMBs = mbs;
22950dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
22960dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
22970dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive ||
22980dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
22990dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
23000dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) {
23010dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
23020dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
23030dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirMBs = mbs;
23040dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
23050dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t ref;
23060dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) {
23070dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
23080dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
23090dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirRef = ref;
23100dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
23110dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
23120dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = mOMX->setParameter(
23130dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            mNode, OMX_IndexParamVideoIntraRefresh,
23140dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            &params, sizeof(params));
23150dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    return err;
23160dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong}
23170dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
23185778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
23195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (iFramesInterval < 0) {
23205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0xFFFFFFFF;
23215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (iFramesInterval == 0) {
23225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0;
23235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_U32 ret = frameRate * iFramesInterval;
23255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return ret;
23265778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
23275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
232896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatic OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) {
232996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    int32_t tmp;
233096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    if (!msg->findInt32("bitrate-mode", &tmp)) {
233196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        return OMX_Video_ControlRateVariable;
233296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    }
233396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
233496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp);
233596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber}
233696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
23375778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
23385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
23395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
23405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
23415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
23425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
234496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
234596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
23465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
23475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
23485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
23495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
23505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
23515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
23535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
23565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&mpeg4type);
23575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPortIndex = kPortIndexOutput;
23585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
23605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
23615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
23635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
23645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nSliceHeaderSpacing = 0;
23675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bSVH = OMX_FALSE;
23685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bGov = OMX_FALSE;
23695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nAllowedPictureTypes =
23715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
23725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
23745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mpeg4type.nPFrames == 0) {
23755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
23765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nBFrames = 0;
23785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nIDCVLCThreshold = 0;
23795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bACPred = OMX_TRUE;
23805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nMaxPacketSize = 256;
23815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nTimeIncRes = 1000;
23825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nHeaderExtension = 0;
23835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bReversibleVLC = OMX_FALSE;
23845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
23865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
23875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
23885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
23895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
23905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
23935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
23955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
23965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
23995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
24005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
24035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
24045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
24065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
24075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
240996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
24105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
24125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
24135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
24165778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
24175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24185778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
24195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
24205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
24215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
24225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
24235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
242596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
242696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
24275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
24285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
24295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
24305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
24315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
24325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
24335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
24345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_H263TYPE h263type;
24375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h263type);
24385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPortIndex = kPortIndexOutput;
24395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
24415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
24425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
24445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
24455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nAllowedPictureTypes =
24485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
24495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
24515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h263type.nPFrames == 0) {
24525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
24535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nBFrames = 0;
24555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
24575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
24585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
24595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
24605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
24615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
24625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
24645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
24665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
24675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
24685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
24705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
24715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bPLUSPTYPEAllowed = OMX_FALSE;
24745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bForceRoundingTypeToZero = OMX_FALSE;
24755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPictureHeaderRepetition = 0;
24765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nGOBHeaderInterval = 0;
24775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
24795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
24805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
24825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
24835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
248596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
24865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
24885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
24895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
24925778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
24935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2494a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar// static
2495a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnarint /* OMX_VIDEO_AVCLEVELTYPE */ ACodec::getAVCLevelFor(
2496a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        int width, int height, int rate, int bitrate,
2497a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        OMX_VIDEO_AVCPROFILETYPE profile) {
2498a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    // convert bitrate to main/baseline profile kbps equivalent
2499a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    switch (profile) {
2500a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        case OMX_VIDEO_AVCProfileHigh10:
2501a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 3000); break;
2502a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        case OMX_VIDEO_AVCProfileHigh:
2503a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 1250); break;
2504a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        default:
2505a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 1000); break;
2506a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    }
2507a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
2508a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    // convert size and rate to MBs
2509a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    width = divUp(width, 16);
2510a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    height = divUp(height, 16);
2511a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    int mbs = width * height;
2512a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    rate *= mbs;
2513a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    int maxDimension = max(width, height);
2514a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
2515a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    static const int limits[][5] = {
2516a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        /*   MBps     MB   dim  bitrate        level */
2517a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    1485,    99,  28,     64, OMX_VIDEO_AVCLevel1  },
2518a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    1485,    99,  28,    128, OMX_VIDEO_AVCLevel1b },
2519a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    3000,   396,  56,    192, OMX_VIDEO_AVCLevel11 },
2520a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    6000,   396,  56,    384, OMX_VIDEO_AVCLevel12 },
2521a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   11880,   396,  56,    768, OMX_VIDEO_AVCLevel13 },
2522a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   11880,   396,  56,   2000, OMX_VIDEO_AVCLevel2  },
2523a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   19800,   792,  79,   4000, OMX_VIDEO_AVCLevel21 },
2524a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   20250,  1620, 113,   4000, OMX_VIDEO_AVCLevel22 },
2525a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   40500,  1620, 113,  10000, OMX_VIDEO_AVCLevel3  },
2526a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  108000,  3600, 169,  14000, OMX_VIDEO_AVCLevel31 },
2527a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  216000,  5120, 202,  20000, OMX_VIDEO_AVCLevel32 },
2528a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  245760,  8192, 256,  20000, OMX_VIDEO_AVCLevel4  },
2529a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  245760,  8192, 256,  50000, OMX_VIDEO_AVCLevel41 },
2530a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  522240,  8704, 263,  50000, OMX_VIDEO_AVCLevel42 },
2531a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  589824, 22080, 420, 135000, OMX_VIDEO_AVCLevel5  },
2532a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  983040, 36864, 543, 240000, OMX_VIDEO_AVCLevel51 },
2533a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        { 2073600, 36864, 543, 240000, OMX_VIDEO_AVCLevel52 },
2534a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    };
2535a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
2536a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    for (size_t i = 0; i < ARRAY_SIZE(limits); i++) {
2537a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        const int (&limit)[5] = limits[i];
2538a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        if (rate <= limit[0] && mbs <= limit[1] && maxDimension <= limit[2]
2539a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar                && bitrate <= limit[3]) {
2540a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            return limit[4];
2541a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        }
2542a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    }
2543a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    return 0;
2544a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar}
2545a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
25465778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
25475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
25485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
25495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
25505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
25515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
255396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
255496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
25555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
25565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
25575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
25585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
25595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
25605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
25615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
25625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25640dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = OK;
25650dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    int32_t intraRefreshMode = 0;
25660dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) {
25670dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode);
25680dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (err != OK) {
25690dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
25700dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong                    err, intraRefreshMode);
25710dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return err;
25720dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
25730dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
25740dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
25755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_AVCTYPE h264type;
25765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h264type);
25775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nPortIndex = kPortIndexOutput;
25785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25790dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    err = mOMX->getParameter(
25805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
25815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
25835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
25845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nAllowedPictureTypes =
25875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
25885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
25905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
25915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
25925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
25935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
25945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
25955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
25975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
25995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
26005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
26015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
26035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
26045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // XXX
26077c25df82dfc8bbedb58608242f0d923a4594bb14James Dong    if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) {
26087c25df82dfc8bbedb58608242f0d923a4594bb14James Dong        ALOGW("Use baseline profile instead of %d for AVC recording",
26097c25df82dfc8bbedb58608242f0d923a4594bb14James Dong            h264type.eProfile);
26105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
26115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
26145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nSliceHeaderSpacing = 0;
26155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bUseHadamard = OMX_TRUE;
26165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefFrames = 1;
26175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nBFrames = 0;
26185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
26195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (h264type.nPFrames == 0) {
26205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
26215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
26225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx10ActiveMinus1 = 0;
26235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx11ActiveMinus1 = 0;
26245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bEntropyCodingCABAC = OMX_FALSE;
26255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bWeightedPPrediction = OMX_FALSE;
26265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bconstIpred = OMX_FALSE;
26275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirect8x8Inference = OMX_FALSE;
26285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirectSpatialTemporal = OMX_FALSE;
26295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nCabacInitIdc = 0;
26305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.nBFrames != 0) {
26335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
26345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableUEP = OMX_FALSE;
26375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableFMO = OMX_FALSE;
26385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableASO = OMX_FALSE;
26395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableRS = OMX_FALSE;
26405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bFrameMBsOnly = OMX_TRUE;
26415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bMBAFF = OMX_FALSE;
26425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
26435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
26455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
26465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
26485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
26495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
265196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return configureBitrate(bitrate, bitrateMode);
26525778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
26535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2654c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachadstatus_t ACodec::setupHEVCEncoderParameters(const sp<AMessage> &msg) {
2655c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    int32_t bitrate, iFrameInterval;
2656c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findInt32("bitrate", &bitrate)
2657c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
2658c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return INVALID_OPERATION;
2659c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2660c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2661c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
2662c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2663c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    float frameRate;
2664c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findFloat("frame-rate", &frameRate)) {
2665c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t tmp;
2666c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("frame-rate", &tmp)) {
2667c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
2668c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
2669c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        frameRate = (float)tmp;
2670c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2671c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2672c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_PARAM_HEVCTYPE hevcType;
2673c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    InitOMXParams(&hevcType);
2674c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    hevcType.nPortIndex = kPortIndexOutput;
2675c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2676c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    status_t err = OK;
2677c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    err = mOMX->getParameter(
2678c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
2679c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
2680c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
2681c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2682c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2683c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    int32_t profile;
2684c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (msg->findInt32("profile", &profile)) {
2685c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t level;
2686c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("level", &level)) {
2687c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
2688c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
2689c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2690c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        err = verifySupportForProfileAndLevel(profile, level);
2691c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (err != OK) {
2692c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return err;
2693c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
2694c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2695c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eProfile = static_cast<OMX_VIDEO_HEVCPROFILETYPE>(profile);
2696c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eLevel = static_cast<OMX_VIDEO_HEVCLEVELTYPE>(level);
2697c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2698c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2699c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    // TODO: Need OMX structure definition for setting iFrameInterval
2700c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2701c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    err = mOMX->setParameter(
2702c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
2703c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
2704c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
2705c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2706c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2707c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    return configureBitrate(bitrate, bitrateMode);
2708c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad}
2709c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
271089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huberstatus_t ACodec::setupVPXEncoderParameters(const sp<AMessage> &msg) {
271189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    int32_t bitrate;
27124154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    int32_t iFrameInterval = 0;
27134154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    size_t tsLayers = 0;
27144154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE pattern =
27154154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        OMX_VIDEO_VPXTemporalLayerPatternNone;
27164154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    static const uint32_t kVp8LayerRateAlloction
27174154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS]
27184154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS] = {
27194154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        {100, 100, 100},  // 1 layer
27204154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 60, 100, 100},  // 2 layers {60%, 40%}
27214154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 40,  60, 100},  // 3 layers {40%, 20%, 40%}
27224154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    };
272389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    if (!msg->findInt32("bitrate", &bitrate)) {
272489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        return INVALID_OPERATION;
272589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    }
27264154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    msg->findInt32("i-frame-interval", &iFrameInterval);
272789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
272889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
272989b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
27304154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    float frameRate;
27314154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (!msg->findFloat("frame-rate", &frameRate)) {
27324154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        int32_t tmp;
27334154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (!msg->findInt32("frame-rate", &tmp)) {
27344154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            return INVALID_OPERATION;
27354154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
27364154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        frameRate = (float)tmp;
27374154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
27384154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
27394154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    AString tsSchema;
27404154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (msg->findString("ts-schema", &tsSchema)) {
27414154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (tsSchema == "webrtc.vp8.1-layer") {
27424154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
27434154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 1;
27444154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else if (tsSchema == "webrtc.vp8.2-layer") {
27454154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
27464154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 2;
27474154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else if (tsSchema == "webrtc.vp8.3-layer") {
27484154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
27494154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 3;
27504154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else {
27514154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            ALOGW("Unsupported ts-schema [%s]", tsSchema.c_str());
27524154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
27534154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
27544154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
27554154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
27564154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    InitOMXParams(&vp8type);
27574154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    vp8type.nPortIndex = kPortIndexOutput;
27584154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    status_t err = mOMX->getParameter(
27594154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
27604154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            &vp8type, sizeof(vp8type));
27614154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
27624154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (err == OK) {
27634154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (iFrameInterval > 0) {
27644154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nKeyFrameInterval = setPFramesSpacing(iFrameInterval, frameRate);
27654154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
27664154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.eTemporalPattern = pattern;
27674154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.nTemporalLayerCount = tsLayers;
27684154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (tsLayers > 0) {
27694154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            for (size_t i = 0; i < OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS; i++) {
27704154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                vp8type.nTemporalLayerBitrateRatio[i] =
27714154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                    kVp8LayerRateAlloction[tsLayers - 1][i];
27724154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            }
27734154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
27744154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (bitrateMode == OMX_Video_ControlRateConstant) {
27754154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMinQuantizer = 2;
27764154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMaxQuantizer = 63;
27774154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
27784154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
27794154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        err = mOMX->setParameter(
27804154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
27814154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                &vp8type, sizeof(vp8type));
27824154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (err != OK) {
27834154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            ALOGW("Extended VP8 parameters set failed: %d", err);
27844154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
27854154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
27864154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
278789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    return configureBitrate(bitrate, bitrateMode);
278889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber}
278989b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
27905778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::verifySupportForProfileAndLevel(
27915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t profile, int32_t level) {
27925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
27935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&params);
27945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    params.nPortIndex = kPortIndexOutput;
27955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (params.nProfileIndex = 0;; ++params.nProfileIndex) {
27975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
27985778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode,
27995778822d86b0337407514b9372562b86edfa91cdAndreas Huber                OMX_IndexParamVideoProfileLevelQuerySupported,
28005778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &params,
28015778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sizeof(params));
28025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
28045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
28055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
28065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
28085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
28095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (profile == supportedProfile && level <= supportedLevel) {
28115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OK;
28125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
28135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28145778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
28155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
281696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatus_t ACodec::configureBitrate(
281796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) {
28185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
28195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&bitrateType);
28205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
28215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
28235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
28245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
28255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
28275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
28285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
283096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    bitrateType.eControlRate = bitrateMode;
28315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nTargetBitrate = bitrate;
28325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
28345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
28355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
28365778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
28375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28385778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupErrorCorrectionParameters() {
28395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
28405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&errorCorrectionType);
28415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nPortIndex = kPortIndexOutput;
28425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
28445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
28455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
28465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
28485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OK;  // Optional feature. Ignore this failure
28495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableHEC = OMX_FALSE;
28525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableResync = OMX_TRUE;
28535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nResynchMarkerSpacing = 256;
28545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
28555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableRVLC = OMX_FALSE;
28565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
28585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
28595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
28605778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
28615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2862f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoFormatOnPort(
2863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
2864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat) {
2865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
2866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
2867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
2868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
2870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
2872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
2875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
2877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // XXX Need a (much) better heuristic to compute input buffer sizes.
2878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const size_t X = 64 * 1024;
2879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (def.nBufferSize < X) {
2880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.nBufferSize = X;
2881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
2885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameWidth = width;
2887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameHeight = height;
2888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
2890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eCompressionFormat = compressionFormat;
2891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eColorFormat = OMX_COLOR_FormatUnused;
2892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
2895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
2898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2900f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::initNativeWindow() {
2901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL) {
2902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
2903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
2906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2909d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Hubersize_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
2910d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    size_t n = 0;
2911d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2912d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2913d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        const BufferInfo &info = mBuffers[portIndex].itemAt(i);
2914d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2915d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
2916d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            ++n;
2917d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        }
2918d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    }
2919d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2920d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    return n;
2921d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber}
2922d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
29237e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubersize_t ACodec::countBuffersOwnedByNativeWindow() const {
29247e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    size_t n = 0;
29257e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
29267e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
29277e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
29287e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
29297e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
29307e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            ++n;
29317e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        }
29327e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
29337e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
29347e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    return n;
29357e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
29367e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
29377e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubervoid ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
29387e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (mNativeWindow == NULL) {
29397e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        return;
29407e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
29417e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
2942e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    while (countBuffersOwnedByNativeWindow() > mNumUndequeuedBuffers
29437e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            && dequeueBufferFromNativeWindow() != NULL) {
2944c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        // these buffers will be submitted as regular buffers; account for this
2945c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        if (mStoreMetaDataInOutputBuffers && mMetaDataBuffersToSubmit > 0) {
2946c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar            --mMetaDataBuffersToSubmit;
2947c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        }
29487e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
29497e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
29507e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
2951f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs(
2952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
2953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
2955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus != BufferInfo::OWNED_BY_US
2957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
2958609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGV("[%s] Buffer %u on port %u still has status %d",
2959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mComponentName.c_str(),
2960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info->mBufferID, portIndex, info->mStatus);
2961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
2962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2968f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs() {
2969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return allYourBuffersAreBelongToUs(kPortIndexInput)
2970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        && allYourBuffersAreBelongToUs(kPortIndexOutput);
2971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2973f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::deferMessage(const sp<AMessage> &msg) {
2974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool wasEmptyBefore = mDeferredQueue.empty();
2975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.push_back(msg);
2976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2978f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::processDeferredMessages() {
2979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> > queue = mDeferredQueue;
2980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.clear();
2981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> >::iterator it = queue.begin();
2983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while (it != queue.end()) {
2984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        onMessageReceived(*it++);
2985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
298803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar// static
2989229d242665c612fd97431d1e7ac004823b47f181Lajos Molnarbool ACodec::describeDefaultColorFormat(DescribeColorFormatParams &params) {
299003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    MediaImage &image = params.sMediaImage;
299103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    memset(&image, 0, sizeof(image));
299203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
299303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mType = MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
299403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mNumPlanes = 0;
299503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
299603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    const OMX_COLOR_FORMATTYPE fmt = params.eColorFormat;
299703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mWidth = params.nFrameWidth;
299803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mHeight = params.nFrameHeight;
299903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
300003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    // only supporting YUV420
300103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    if (fmt != OMX_COLOR_FormatYUV420Planar &&
300203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        fmt != OMX_COLOR_FormatYUV420PackedPlanar &&
300303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        fmt != OMX_COLOR_FormatYUV420SemiPlanar &&
300403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        fmt != OMX_COLOR_FormatYUV420PackedSemiPlanar) {
300503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        ALOGW("do not know color format 0x%x = %d", fmt, fmt);
3006229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return false;
300703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    }
300803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
3009b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    // TEMPORARY FIX for some vendors that advertise sliceHeight as 0
3010b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    if (params.nStride != 0 && params.nSliceHeight == 0) {
3011b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        ALOGW("using sliceHeight=%u instead of what codec advertised (=0)",
3012b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar                params.nFrameHeight);
3013b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        params.nSliceHeight = params.nFrameHeight;
3014b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    }
3015b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar
3016b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    // we need stride and slice-height to be non-zero
3017b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    if (params.nStride == 0 || params.nSliceHeight == 0) {
3018b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        ALOGW("cannot describe color format 0x%x = %d with stride=%u and sliceHeight=%u",
3019b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar                fmt, fmt, params.nStride, params.nSliceHeight);
3020b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        return false;
3021b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    }
3022b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar
302303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    // set-up YUV format
302403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mType = MediaImage::MEDIA_IMAGE_TYPE_YUV;
302503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mNumPlanes = 3;
302603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mBitDepth = 8;
302703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mOffset = 0;
302803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mColInc = 1;
302903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mRowInc = params.nStride;
303003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mHorizSubsampling = 1;
303103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mVertSubsampling = 1;
303203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
303303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    switch (fmt) {
303403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420Planar: // used for YV12
303503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420PackedPlanar:
303603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight;
303703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mColInc = 1;
303803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mRowInc = params.nStride / 2;
303903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mHorizSubsampling = 2;
304003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mVertSubsampling = 2;
304103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
304203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset
304303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    + (params.nStride * params.nSliceHeight / 4);
304403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mColInc = 1;
304503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mRowInc = params.nStride / 2;
304603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mHorizSubsampling = 2;
304703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mVertSubsampling = 2;
304803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            break;
304903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
305003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420SemiPlanar:
305103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            // FIXME: NV21 for sw-encoder, NV12 for decoder and hw-encoder
305203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420PackedSemiPlanar:
305303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            // NV12
305403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight;
305503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mColInc = 2;
305603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mRowInc = params.nStride;
305703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mHorizSubsampling = 2;
305803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mVertSubsampling = 2;
305903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
306003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset + 1;
306103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mColInc = 2;
306203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mRowInc = params.nStride;
306303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mHorizSubsampling = 2;
306403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mVertSubsampling = 2;
306503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            break;
306603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
306703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        default:
306803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            TRESPASS();
306903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    }
3070229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    return true;
3071229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar}
3072229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3073229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar// static
3074229d242665c612fd97431d1e7ac004823b47f181Lajos Molnarbool ACodec::describeColorFormat(
3075229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        const sp<IOMX> &omx, IOMX::node_id node,
3076229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        DescribeColorFormatParams &describeParams)
3077229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar{
3078229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    OMX_INDEXTYPE describeColorFormatIndex;
3079229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    if (omx->getExtensionIndex(
3080229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            node, "OMX.google.android.index.describeColorFormat",
3081229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            &describeColorFormatIndex) != OK ||
3082229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        omx->getParameter(
3083229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            node, describeColorFormatIndex,
3084229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            &describeParams, sizeof(describeParams)) != OK) {
3085229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return describeDefaultColorFormat(describeParams);
3086229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    }
3087229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    return describeParams.sMediaImage.mType !=
3088229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
3089229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar}
3090229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3091229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar// static
3092229d242665c612fd97431d1e7ac004823b47f181Lajos Molnarbool ACodec::isFlexibleColorFormat(
3093229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar         const sp<IOMX> &omx, IOMX::node_id node,
3094229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar         uint32_t colorFormat, OMX_U32 *flexibleEquivalent) {
3095229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    DescribeColorFormatParams describeParams;
3096229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    InitOMXParams(&describeParams);
3097229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.eColorFormat = (OMX_COLOR_FORMATTYPE)colorFormat;
3098229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    // reasonable dummy values
3099229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nFrameWidth = 128;
3100229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nFrameHeight = 128;
3101229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nStride = 128;
3102229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nSliceHeight = 128;
3103229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3104229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    CHECK(flexibleEquivalent != NULL);
3105229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3106229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    if (!describeColorFormat(omx, node, describeParams)) {
3107229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return false;
3108229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    }
3109229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3110229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    const MediaImage &img = describeParams.sMediaImage;
3111229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    if (img.mType == MediaImage::MEDIA_IMAGE_TYPE_YUV) {
3112229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        if (img.mNumPlanes != 3 ||
3113229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            img.mPlane[img.Y].mHorizSubsampling != 1 ||
3114229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            img.mPlane[img.Y].mVertSubsampling != 1) {
3115229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            return false;
3116229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
3117229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3118229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        // YUV 420
3119229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        if (img.mPlane[img.U].mHorizSubsampling == 2
3120229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.U].mVertSubsampling == 2
3121229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.V].mHorizSubsampling == 2
3122229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.V].mVertSubsampling == 2) {
3123229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            // possible flexible YUV420 format
3124229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            if (img.mBitDepth <= 8) {
3125229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar               *flexibleEquivalent = OMX_COLOR_FormatYUV420Flexible;
3126229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar               return true;
3127229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            }
3128229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
3129229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    }
3130229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    return false;
313103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar}
313203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
3133e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarstatus_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> &notify) {
3134e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    // TODO: catch errors an return them instead of using CHECK
313531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
313631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    InitOMXParams(&def);
3137e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    def.nPortIndex = portIndex;
313831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
313931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ(mOMX->getParameter(
314031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)),
314131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber             (status_t)OK);
314231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3143e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ((int)def.eDir,
3144e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            (int)(portIndex == kPortIndexOutput ? OMX_DirOutput : OMX_DirInput));
314531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
314631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    switch (def.eDomain) {
314731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainVideo:
314831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
314931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
3150e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            switch ((int)videoDef->eCompressionFormat) {
3151e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_VIDEO_CodingUnused:
3152e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3153e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(mIsEncoder ^ (portIndex == kPortIndexOutput));
3154e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
3155e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3156e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("stride", videoDef->nStride);
3157e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("slice-height", videoDef->nSliceHeight);
3158e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("color-format", videoDef->eColorFormat);
3159e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
316003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    DescribeColorFormatParams describeParams;
316103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    InitOMXParams(&describeParams);
316203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    describeParams.eColorFormat = videoDef->eColorFormat;
316303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    describeParams.nFrameWidth = videoDef->nFrameWidth;
316403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    describeParams.nFrameHeight = videoDef->nFrameHeight;
316503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    describeParams.nStride = videoDef->nStride;
316603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    describeParams.nSliceHeight = videoDef->nSliceHeight;
316703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
3168229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                    if (describeColorFormat(mOMX, mNode, describeParams)) {
316903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                        notify->setBuffer(
317003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                                "image-data",
317103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                                ABuffer::CreateAsCopy(
317203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                                        &describeParams.sMediaImage,
317303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                                        sizeof(describeParams.sMediaImage)));
317403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    }
317503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
3176e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_CONFIG_RECTTYPE rect;
3177e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&rect);
3178e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    rect.nPortIndex = kPortIndexOutput;
3179e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3180e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    if (mOMX->getConfig(
3181e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                mNode, OMX_IndexConfigCommonOutputCrop,
3182e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &rect, sizeof(rect)) != OK) {
3183e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nLeft = 0;
3184e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nTop = 0;
3185e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nWidth = videoDef->nFrameWidth;
3186e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nHeight = videoDef->nFrameHeight;
3187e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    }
318831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3189e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nLeft, 0);
3190e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nTop, 0);
3191e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nWidth, 0u);
3192e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nHeight, 0u);
3193e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_LE(rect.nLeft + rect.nWidth - 1, videoDef->nFrameWidth);
3194e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_LE(rect.nTop + rect.nHeight - 1, videoDef->nFrameHeight);
3195e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3196e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setRect(
3197577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            "crop",
3198577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nLeft,
3199577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nTop,
3200e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                            rect.nLeft + rect.nWidth - 1,
3201e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                            rect.nTop + rect.nHeight - 1);
3202e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3203e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3204e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
32054730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
32064730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP8:
32074730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP9:
32084730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                {
32094730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
32104730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    InitOMXParams(&vp8type);
32114730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    vp8type.nPortIndex = kPortIndexOutput;
32124730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    status_t err = mOMX->getParameter(
32134730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            mNode,
32144730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
32154730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            &vp8type,
32164730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            sizeof(vp8type));
32174730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
32184730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    if (err == OK) {
32194730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        AString tsSchema = "none";
32204730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        if (vp8type.eTemporalPattern
32214730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                == OMX_VIDEO_VPXTemporalLayerPatternWebRTC) {
32224730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            switch (vp8type.nTemporalLayerCount) {
32234730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 1:
32244730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
32254730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.1-layer";
32264730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
32274730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
32284730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 2:
32294730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
32304730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.2-layer";
32314730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
32324730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
32334730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 3:
32344730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
32354730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.3-layer";
32364730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
32374730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
32384730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                default:
32394730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
32404730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
32414730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
32424730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            }
32434730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        }
32444730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        notify->setString("ts-schema", tsSchema);
32454730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    }
32464730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    // Fall through to set up mime.
32474730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                }
32484730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
3249e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                default:
3250e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3251e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(mIsEncoder ^ (portIndex == kPortIndexInput));
3252e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    AString mime;
3253e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    if (GetMimeTypeForVideoCoding(
3254e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        videoDef->eCompressionFormat, &mime) != OK) {
3255e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", "application/octet-stream");
3256e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    } else {
3257e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", mime.c_str());
3258e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    }
3259e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3260e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
326131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            }
3262e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3263e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("width", videoDef->nFrameWidth);
3264e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("height", videoDef->nFrameHeight);
326531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
326631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
326731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
326831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainAudio:
326931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
327031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
327131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
327297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            switch ((int)audioDef->eEncoding) {
3273e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingPCM:
3274e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3275e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_PCMMODETYPE params;
3276e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3277e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3278e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3279e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3280e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioPcm,
3281e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3282e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3283e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
328414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_GT(params.nChannels, 0);
3285e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK(params.nChannels == 1 || params.bInterleaved);
3286e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(params.nBitPerSample, 16u);
328714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
328814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.eNumData,
328914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_NumericalDataSigned);
329014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
329114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.ePCMMode,
329214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_AUDIO_PCMModeLinear);
3293e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3294e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
3295e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
3296e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSamplingRate);
3297e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3298e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mChannelMaskPresent) {
3299e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("channel-mask", mChannelMask);
33008b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                    }
3301e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
33028b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                }
33039806555d3930be43e11106281dee354820ac1c88Andreas Huber
3304e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAAC:
3305e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3306e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AACPROFILETYPE params;
3307e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3308e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3309e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3310e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3311e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAac,
3312e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3313e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3314e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3315e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
3316e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
3317e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
3318e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
3319e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
3320e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3321e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAMR:
3322e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3323e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AMRTYPE params;
3324e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3325e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
33269806555d3930be43e11106281dee354820ac1c88Andreas Huber
3327e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3328e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAmr,
3329e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3330e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3331e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3332e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", 1);
3333e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) {
3334e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
3335e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_WB);
3336e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3337e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 16000);
3338e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    } else {
3339e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
3340e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
3341e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3342e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 8000);
3343e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
3344e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
3345e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
3346e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3347e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingFLAC:
3348e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3349e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_FLACTYPE params;
3350e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3351e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3352e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3353e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3354e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioFlac,
3355e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3356e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3357e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3358e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC);
3359e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
3360e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
3361e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
3362e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
3363e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3364e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingMP3:
3365e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3366e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_MP3TYPE params;
3367e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
3368e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3369e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3370e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_EQ(mOMX->getParameter(
3371e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                mNode, OMX_IndexParamAudioMp3,
3372e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &params, sizeof(params)),
3373e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                             (status_t)OK);
3374e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3375e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MPEG);
3376e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
3377e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
3378e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3379e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
3380e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3381e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingVORBIS:
3382e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3383e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_VORBISTYPE params;
3384e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
3385e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3386e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3387e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_EQ(mOMX->getParameter(
3388e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                mNode, OMX_IndexParamAudioVorbis,
3389e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &params, sizeof(params)),
3390e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                             (status_t)OK);
3391e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3392e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_VORBIS);
3393e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
3394e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
3395e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3396e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
3397e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
339897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                case OMX_AUDIO_CodingAndroidAC3:
339997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                {
340097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    OMX_AUDIO_PARAM_ANDROID_AC3TYPE params;
340197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    InitOMXParams(&params);
3402e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
340397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
340497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    CHECK_EQ((status_t)OK, mOMX->getParameter(
340597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            mNode,
340697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
340797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            &params,
340897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            sizeof(params)));
340997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
341097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AC3);
341197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("channel-count", params.nChannels);
341297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("sample-rate", params.nSampleRate);
341397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    break;
341497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                }
3415e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
34168c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                case OMX_AUDIO_CodingAndroidOPUS:
34178c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                {
34188c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    OMX_AUDIO_PARAM_ANDROID_OPUSTYPE params;
34198c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    InitOMXParams(&params);
34208c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    params.nPortIndex = portIndex;
34218c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
34228c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    CHECK_EQ((status_t)OK, mOMX->getParameter(
34238c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            mNode,
34248c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus,
34258c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            &params,
34268c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            sizeof(params)));
34278c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
34288c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_OPUS);
34298c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("channel-count", params.nChannels);
34308c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("sample-rate", params.nSampleRate);
34318c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    break;
34328c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                }
34338c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
3434e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                default:
3435e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    ALOGE("UNKNOWN AUDIO CODING: %d\n", audioDef->eEncoding);
3436e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    TRESPASS();
3437e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
343831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
343931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
344031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
344131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        default:
344231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            TRESPASS();
344331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    }
344431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3445e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    return OK;
3446e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar}
3447e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3448e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarvoid ACodec::sendFormatChange(const sp<AMessage> &reply) {
3449e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    sp<AMessage> notify = mNotify->dup();
3450e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    notify->setInt32("what", kWhatOutputFormatChanged);
3451e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3452e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ(getPortFormat(kPortIndexOutput, notify), (status_t)OK);
3453e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3454e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    AString mime;
3455e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK(notify->findString("mime", &mime));
3456e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3457e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    int32_t left, top, right, bottom;
3458e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if (mime == MEDIA_MIMETYPE_VIDEO_RAW &&
3459e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        mNativeWindow != NULL &&
3460e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->findRect("crop", &left, &top, &right, &bottom)) {
3461e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        // notify renderer of the crop change
3462e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        // NOTE: native window uses extended right-bottom coordinate
3463e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        reply->setRect("crop", left, top, right + 1, bottom + 1);
3464e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    } else if (mime == MEDIA_MIMETYPE_AUDIO_RAW &&
3465e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar               (mEncoderDelay || mEncoderPadding)) {
3466e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        int32_t channelCount;
3467e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        CHECK(notify->findInt32("channel-count", &channelCount));
3468e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        size_t frameSize = channelCount * sizeof(int16_t);
3469e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        if (mSkipCutBuffer != NULL) {
3470e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            size_t prevbufsize = mSkipCutBuffer->size();
3471e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            if (prevbufsize != 0) {
3472e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                ALOGW("Replacing SkipCutBuffer holding %d "
3473e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                      "bytes",
3474e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                      prevbufsize);
3475e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            }
3476e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        }
3477e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        mSkipCutBuffer = new SkipCutBuffer(
3478e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                mEncoderDelay * frameSize,
3479e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                mEncoderPadding * frameSize);
3480e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
3481e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
348231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->post();
348331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
348431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mSentFormat = true;
348531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber}
348631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
34875778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
3488cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    sp<AMessage> notify = mNotify->dup();
3489d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatError);
3490251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    ALOGE("signalError(omxError %#x, internalError %d)", error, internalError);
3491251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
3492251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (internalError == UNKNOWN_ERROR) { // find better error code
3493251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        const status_t omxStatus = statusFromOMXError(error);
3494251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        if (omxStatus != 0) {
3495251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            internalError = omxStatus;
3496251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        } else {
3497251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            ALOGW("Invalid OMX error %#x", error);
3498251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        }
3499251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
35005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("err", internalError);
3501251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    notify->setInt32("actionCode", ACTION_CODE_FATAL); // could translate from OMX error.
3502cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->post();
3503cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber}
3504cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber
3505bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huberstatus_t ACodec::pushBlankBuffersToNativeWindow() {
3506bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    status_t err = NO_ERROR;
3507bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    ANativeWindowBuffer* anb = NULL;
3508bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int numBufs = 0;
3509bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int minUndequeuedBufs = 0;
3510bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3511bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We need to reconnect to the ANativeWindow as a CPU client to ensure that
3512bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // no frames get dropped by SurfaceFlinger assuming that these are video
3513bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // frames.
3514bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_disconnect(mNativeWindow.get(),
3515bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_MEDIA);
3516bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3517bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
3518bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3519bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
3520bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3521bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3522bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_connect(mNativeWindow.get(),
3523bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_CPU);
3524bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3525bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
3526bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3527bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
3528bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3529bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3530bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffers_geometry(mNativeWindow.get(), 1, 1,
3531bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            HAL_PIXEL_FORMAT_RGBX_8888);
3532bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3533bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffers_geometry failed: %s (%d)",
3534bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3535bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
3536bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3537bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
353887eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin    err = native_window_set_scaling_mode(mNativeWindow.get(),
353987eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
354087eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin    if (err != NO_ERROR) {
354187eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin        ALOGE("error pushing blank_frames: set_scaling_mode failed: %s (%d)",
354287eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin              strerror(-err), -err);
354387eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin        goto error;
3544bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3545bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3546bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_usage(mNativeWindow.get(),
3547bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            GRALLOC_USAGE_SW_WRITE_OFTEN);
3548bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3549bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_usage failed: %s (%d)",
3550bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3551bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
3552bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3553bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3554bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = mNativeWindow->query(mNativeWindow.get(),
3555bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs);
3556bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3557bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: MIN_UNDEQUEUED_BUFFERS query "
3558bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                "failed: %s (%d)", strerror(-err), -err);
3559bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
3560bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3561bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3562bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    numBufs = minUndequeuedBufs + 1;
3563bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffer_count(mNativeWindow.get(), numBufs);
3564bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3565bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffer_count failed: %s (%d)",
3566bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3567bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
3568bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3569bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3570bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We  push numBufs + 1 buffers to ensure that we've drawn into the same
3571bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // buffer twice.  This should guarantee that the buffer has been displayed
3572bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // on the screen and then been replaced, so an previous video frames are
3573bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // guaranteed NOT to be currently displayed.
3574bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    for (int i = 0; i < numBufs + 1; i++) {
35751e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        int fenceFd = -1;
35761e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &anb);
3577bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3578bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: dequeueBuffer failed: %s (%d)",
3579bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3580bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
3581bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3582bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3583bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
3584bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3585bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Fill the buffer with the a 1x1 checkerboard pattern ;)
3586bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        uint32_t* img = NULL;
3587bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
3588bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3589bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: lock failed: %s (%d)",
3590bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3591bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
3592bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3593bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3594bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        *img = 0;
3595bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3596bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->unlock();
3597bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3598bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: unlock failed: %s (%d)",
3599bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3600bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
3601bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3602bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3603bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->queueBuffer(mNativeWindow.get(),
36041e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                buf->getNativeBuffer(), -1);
3605bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3606bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: queueBuffer failed: %s (%d)",
3607bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3608bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
3609bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3610bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3611bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        anb = NULL;
3612bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3613bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3614bc098410be55f9d96f394b3981a0c482b83859b6Andreas Hubererror:
3615bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3616bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3617bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after an error.
3618bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (anb != NULL) {
36191e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis            mNativeWindow->cancelBuffer(mNativeWindow.get(), anb, -1);
3620bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3621bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3622bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_disconnect(mNativeWindow.get(),
3623bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
3624bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_connect(mNativeWindow.get(),
3625bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
3626bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3627bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
3628bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    } else {
3629bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after success.
3630bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_disconnect(mNativeWindow.get(),
3631bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
3632bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3633bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
3634bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3635bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
3636bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3637bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3638bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_connect(mNativeWindow.get(),
3639bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
3640bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3641bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
3642bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3643bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
3644bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3645bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3646bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return NO_ERROR;
3647bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3648bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber}
3649bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3652eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberACodec::PortDescription::PortDescription() {
3653eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3654eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3655496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t ACodec::requestIDRFrame() {
3656496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    if (!mIsEncoder) {
3657496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        return ERROR_UNSUPPORTED;
3658496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    }
3659496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
3660496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    OMX_CONFIG_INTRAREFRESHVOPTYPE params;
3661496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    InitOMXParams(&params);
3662496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
3663496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.nPortIndex = kPortIndexOutput;
3664496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.IntraRefreshVOP = OMX_TRUE;
3665496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
3666496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    return mOMX->setConfig(
3667496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            mNode,
3668496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            OMX_IndexConfigVideoIntraVOPRefresh,
3669496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            &params,
3670496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            sizeof(params));
3671496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
3672496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
3673eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubervoid ACodec::PortDescription::addBuffer(
3674eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        IOMX::buffer_id id, const sp<ABuffer> &buffer) {
3675eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBufferIDs.push_back(id);
3676eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBuffers.push_back(buffer);
3677eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3678eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3679eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersize_t ACodec::PortDescription::countBuffers() {
3680eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.size();
3681eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3682eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3683eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberIOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const {
3684eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.itemAt(index);
3685eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3686eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3687eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const {
3688eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBuffers.itemAt(index);
3689eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3690eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3691eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber////////////////////////////////////////////////////////////////////////////////
3692eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3693f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
3694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : AState(parentState),
3695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mCodec(codec) {
3696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3698ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas HuberACodec::BaseState::PortMode ACodec::BaseState::getPortMode(
3699ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
3700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return KEEP_BUFFERS;
3701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3703f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
3704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatInputBufferFilled:
3706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onInputBufferFilled(msg);
3708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatOutputBufferDrained:
3712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onOutputBufferDrained(msg);
3714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatOMXMessage:
3718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXMessage(msg);
3720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
37227cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
37237cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
37247cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
3725251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            // This may result in an app illegal state exception.
37267cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            ALOGE("Message 0x%x was not handled", msg->what());
37277cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
37287cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            return true;
37297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
37307cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
3731ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        case ACodec::kWhatOMXDied:
3732ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        {
3733251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            // This will result in kFlagSawMediaServerDie handling in MediaCodec.
3734ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            ALOGE("OMX/mediaserver died, signalling error!");
3735ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT);
3736ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            break;
3737ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        }
3738ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
3741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3746f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
3747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t type;
3748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findInt32("type", &type));
3749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
37505e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // there is a possibility that this is an outstanding message for a
37515e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // codec that we have already destroyed
37525e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    if (mCodec->mNode == NULL) {
37535e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar        ALOGI("ignoring message as already freed component: %s",
37545e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar                msg->debugString().c_str());
37555e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar        return true;
37565e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    }
37575e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar
3758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::node_id nodeID;
3759609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("node", (int32_t*)&nodeID));
3760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(nodeID, mCodec->mNode);
3761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (type) {
3763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EVENT:
3764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t event, data1, data2;
3766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("event", &event));
3767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data1", &data1));
3768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data2", &data2));
3769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
37700af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            if (event == OMX_EventCmdComplete
37710af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data1 == OMX_CommandFlush
37720af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data2 == (int32_t)OMX_ALL) {
37730af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // Use of this notification is not consistent across
37740af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // implementations. We'll drop this notification and rely
37750af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // on flush-complete notifications on the individual port
37760af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // indices instead.
37770af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
37780af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                return true;
37790af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            }
37800af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
3781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEvent(
3782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_EVENTTYPE>(event),
3783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data1),
3784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data2));
3785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EMPTY_BUFFER_DONE:
3788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
3790609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
3791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEmptyBufferDone(bufferID);
3793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::FILL_BUFFER_DONE:
3796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
3798609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
3799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t rangeOffset, rangeLength, flags;
3801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs;
3802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_offset", &rangeOffset));
3804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_length", &rangeLength));
3805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("flags", &flags));
3806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt64("timestamp", &timeUs));
3807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXFillBufferDone(
3809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    bufferID,
3810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (size_t)rangeOffset, (size_t)rangeLength,
3811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (OMX_U32)flags,
3812784e24e386b088c05d653ab482f2e95cb53e3d01Andy Hung                    timeUs);
3813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
3817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3821f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEvent(
3822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (event != OMX_EventError) {
38243856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] EVENT(%d, 0x%08lx, 0x%08lx)",
3825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mCodec->mComponentName.c_str(), event, data1, data2);
3826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return false;
3828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
383029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block    ALOGE("[%s] ERROR(0x%08lx)", mCodec->mComponentName.c_str(), data1);
3831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3832251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // verify OMX component sends back an error we expect.
3833251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    OMX_ERRORTYPE omxError = (OMX_ERRORTYPE)data1;
3834251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (!isOMXError(omxError)) {
3835251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        ALOGW("Invalid OMX error %#x", omxError);
3836251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        omxError = OMX_ErrorUndefined;
3837251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
3838251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    mCodec->signalError(omxError);
3839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3840f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3843f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID) {
38443856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] onOMXEmptyBufferDone %p",
3845349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber         mCodec->mComponentName.c_str(), bufferID);
3846349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexInput, bufferID);
3849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3850f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
3851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
385396e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // We're in "store-metadata-in-buffers" mode, the underlying
385496e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // OMX component had access to data that's implicitly refcounted
385596e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // by this "MediaBuffer" object. Now that the OMX component has
385696e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // told us that it's done with the input buffer, we can decrement
385796e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // the mediaBuffer's reference count.
385896e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    info->mData->setMediaBufferBase(NULL);
3859d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
3861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            postFillThisBuffer(info);
3868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();  // Not currently used
3874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3881f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
3882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
3883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
3887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
3889d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatFillThisBuffer);
3890609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    notify->setInt32("buffer-id", info->mBufferID);
3891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mData->meta()->clear();
38932d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    notify->setBuffer("buffer", info->mData);
3894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec->id());
3896609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    reply->setInt32("buffer-id", info->mBufferID);
3897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setMessage("reply", reply);
3899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->post();
3901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
3903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3905f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
3906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
3907609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
39082d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    sp<ABuffer> buffer;
3909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t err = OK;
39105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool eos = false;
3911a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar    PortMode mode = getPortMode(kPortIndexInput);
39125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39132d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    if (!msg->findBuffer("buffer", &buffer)) {
3914a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar        /* these are unfilled buffers returned by client */
3915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findInt32("err", &err));
3916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
39177fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        if (err == OK) {
39187fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            /* buffers with no errors are returned on MediaCodec.flush */
39197fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            mode = KEEP_BUFFERS;
39207fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        } else {
39217fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            ALOGV("[%s] saw error %d instead of an input buffer",
39227fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                 mCodec->mComponentName.c_str(), err);
39237fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            eos = true;
39247fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        }
39253831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
39262d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber        buffer.clear();
3927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
39295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
39305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
39315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
39325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = ERROR_END_OF_STREAM;
39335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
39345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
3936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_UPSTREAM);
3937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
39435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (eos) {
3944dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (!mCodec->mPortEOS[kPortIndexInput]) {
3945dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
3946dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mInputEOSResult = err;
3947dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
3948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
39545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
3955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int64_t timeUs;
3956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
3957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
3959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t isCSD;
3961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
3962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
3963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
39655778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (eos) {
39665778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    flags |= OMX_BUFFERFLAG_EOS;
39675778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
39685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer != info->mData) {
3970d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGV("[%s] Needs to copy input data for buffer %p. (%p != %p)",
3971d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(),
3972d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         bufferID,
3973d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         buffer.get(), info->mData.get());
3974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    CHECK_LE(buffer->size(), info->mData->capacity());
3976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    memcpy(info->mData->data(), buffer->data(), buffer->size());
3977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3979078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
39803856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ codec specific data",
3981078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID);
39825778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else if (flags & OMX_BUFFERFLAG_EOS) {
39835778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] calling emptyBuffer %p w/ EOS",
39845778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str(), bufferID);
3985078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                } else {
3986d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3987d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGI("[%s] calling emptyBuffer %p w/ time %lld us",
3988d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
3989d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#else
39903856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ time %lld us",
3991078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
3992d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3993078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                }
3994349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3995d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3996d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ACodec::BufferStats stats;
3997d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
3998d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mFillBufferDoneTimeUs = -1ll;
3999d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mCodec->mBufferStats.add(timeUs, stats);
4000d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
4001d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4002054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                if (mCodec->mStoreMetaDataInOutputBuffers) {
4003054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    // try to submit an output buffer for each input buffer
4004054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    PortMode outputMode = getPortMode(kPortIndexOutput);
4005054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4006054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    ALOGV("MetaDataBuffersToSubmit=%u portMode=%s",
4007054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            mCodec->mMetaDataBuffersToSubmit,
4008054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            (outputMode == FREE_BUFFERS ? "FREE" :
4009054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                             outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
4010054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    if (outputMode == RESUBMIT_BUFFERS) {
4011e53350373ac516257b4f8956ff1e3f1ac48f607eLajos Molnar                        mCodec->submitOutputMetaDataBuffer();
4012054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    }
4013054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                }
4014054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
4016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
4017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
4018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
4019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            buffer->size(),
4020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            flags,
4021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            timeUs),
4022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
40265778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (!eos) {
40275778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    getMoreInputDataIfPossible();
40285778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
40295778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] Signalled EOS on the input port",
40305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str());
40315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40325778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
40335778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mInputEOSResult = err;
40345778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
4035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
4036dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (err != ERROR_END_OF_STREAM) {
40373856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port "
4038dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         "due to error %d",
4039dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str(), err);
4040dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                } else {
40413856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port",
4042dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str());
4043dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
4044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
40453856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] calling emptyBuffer %p signalling EOS",
4046349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                     mCodec->mComponentName.c_str(), bufferID);
4047349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
4049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
4050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
4051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
4052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
4053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_BUFFERFLAG_EOS,
4054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0),
4055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexInput] = true;
4060dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                mCodec->mInputEOSResult = err;
4061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4064625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih
4065625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih        default:
4066625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
4067625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih            break;
4068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4071f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::getMoreInputDataIfPossible() {
4072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
4073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
4074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *eligible = NULL;
4077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
4079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
4080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4081f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
4082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
4083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // There's already a "read" pending.
4084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
4085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4086f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
4087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_US) {
4089f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            eligible = info;
4090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (eligible == NULL) {
4094f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
4095f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(eligible);
4098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4100f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXFillBufferDone(
4101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferID,
4102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        size_t rangeOffset, size_t rangeLength,
4103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 flags,
4104784e24e386b088c05d653ab482f2e95cb53e3d01Andy Hung        int64_t timeUs) {
4105609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] onOMXFillBufferDone %u time %" PRId64 " us, flags = 0x%08x",
41065778822d86b0337407514b9372562b86edfa91cdAndreas Huber         mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
4107349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
4109d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4110d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
4111d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    index = mCodec->mBufferStats.indexOfKey(timeUs);
4112d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (index >= 0) {
4113d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
4114d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
4115d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4116d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ALOGI("frame PTS %lld: %lld",
4117d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                timeUs,
4118d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
4119d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4120d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mCodec->mBufferStats.removeItemsAt(index);
4121d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats = NULL;
4122d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
4123d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
4124d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
4126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
4127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
4129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4130054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mDequeuedAt = ++mCodec->mDequeueCounter;
4131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
4132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
4134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
41415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (rangeLength == 0 && !(flags & OMX_BUFFERFLAG_EOS)) {
4142609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                ALOGV("[%s] calling fillBuffer %u",
41435778822d86b0337407514b9372562b86edfa91cdAndreas Huber                     mCodec->mComponentName.c_str(), info->mBufferID);
4144349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
41455778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK_EQ(mCodec->mOMX->fillBuffer(
41465778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mCodec->mNode, info->mBufferID),
41475778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         (status_t)OK);
4148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
41495778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
41505778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
41515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
415231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4153577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            sp<AMessage> reply =
4154577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                new AMessage(kWhatOutputBufferDrained, mCodec->id());
4155577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
41564bdda35319d5f46efea2089b865c8a64816389cdMarco Nelissen            if (!mCodec->mSentFormat && rangeLength > 0) {
4157577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->sendFormatChange(reply);
41585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
4159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4160308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            if (mCodec->mUseMetadataOnEncoderOutput) {
4161308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                native_handle_t* handle =
4162308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        *(native_handle_t**)(info->mData->data() + 4);
4163308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setPointer("handle", handle);
4164308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeOffset", rangeOffset);
4165308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeLength", rangeLength);
4166308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            } else {
4167308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->setRange(rangeOffset, rangeLength);
4168308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            }
4169496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#if 0
417021ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen            if (mCodec->mNativeWindow == NULL) {
4171496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                if (IsIDR(info->mData)) {
4172496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                    ALOGI("IDR frame");
4173496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                }
41745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
417521ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen#endif
4176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
41778b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            if (mCodec->mSkipCutBuffer != NULL) {
41788b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                mCodec->mSkipCutBuffer->submit(info->mData);
41798b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            }
41805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mData->meta()->setInt64("timeUs", timeUs);
4181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
41825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4183d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatDrainThisBuffer);
4184609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            notify->setInt32("buffer-id", info->mBufferID);
41852d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            notify->setBuffer("buffer", info->mData);
41865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("flags", flags);
4187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4188609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            reply->setInt32("buffer-id", info->mBufferID);
4189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
41905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setMessage("reply", reply);
4191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
41925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->post();
41935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
4195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (flags & OMX_BUFFERFLAG_EOS) {
41975778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
41985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                sp<AMessage> notify = mCodec->mNotify->dup();
4200d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar                notify->setInt32("what", CodecBase::kWhatEOS);
4201dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                notify->setInt32("err", mCodec->mInputEOSResult);
4202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->post();
4203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexOutput] = true;
4205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
4212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
4214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
4215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4222f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
4223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
4224609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
4225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
4226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
4227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
4228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM);
4229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4230577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    android_native_rect_t crop;
4231577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    if (msg->findRect("crop",
4232577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            &crop.left, &crop.top, &crop.right, &crop.bottom)) {
4233577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar        CHECK_EQ(0, native_window_set_crop(
4234577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->mNativeWindow.get(), &crop));
4235577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    }
4236577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
4237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t render;
4238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mNativeWindow != NULL
42396aade6058521b0dbd35a9a4620f4d04f02f90444Marco Nelissen            && msg->findInt32("render", &render) && render != 0
424079ee2399b67c7a11042c5904dc1309712a76f8cbJianzheng Zhou            && info->mData != NULL && info->mData->size() != 0) {
42416fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        ATRACE_NAME("render");
4242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The client wants this buffer to be rendered.
4243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4244fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        int64_t timestampNs = 0;
4245fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        if (!msg->findInt64("timestampNs", &timestampNs)) {
4246fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // TODO: it seems like we should use the timestamp
4247fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // in the (media)buffer as it potentially came from
4248fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // an input surface, but we did not propagate it prior to
4249fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // API 20.  Perhaps check for target SDK version.
4250fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#if 0
4251fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            if (info->mData->meta()->findInt64("timeUs", &timestampNs)) {
425247aea1f7c58f5302b16822f9e7e1763f2af04ef5Lajos Molnar                ALOGV("using buffer PTS of %" PRId64, timestampNs);
4253fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar                timestampNs *= 1000;
4254fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            }
4255fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#endif
4256fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
4257fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
42585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err;
4259fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        err = native_window_set_buffers_timestamp(mCodec->mNativeWindow.get(), timestampNs);
4260fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        if (err != OK) {
4261fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            ALOGW("failed to set buffer timestamp: %d", err);
4262fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
4263fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
42645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if ((err = mCodec->mNativeWindow->queueBuffer(
4265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNativeWindow.get(),
42661e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                    info->mGraphicBuffer.get(), -1)) == OK) {
4267cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
4268cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        } else {
4269251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
4270cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
4271cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        }
4272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
42736fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        if (mCodec->mNativeWindow != NULL &&
42746fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar            (info->mData == NULL || info->mData->size() != 0)) {
42756fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar            ATRACE_NAME("frame-drop");
42766fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        }
4277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_US;
4278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
4281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
4286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // We cannot resubmit the buffer we just rendered, dequeue
4289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // the spare instead.
4290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info = mCodec->dequeueBufferFromNativeWindow();
4292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (!mCodec->mPortEOS[kPortIndexOutput]) {
4299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // We cannot resubmit the buffer we just rendered, dequeue
4301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // the spare instead.
4302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info = mCodec->dequeueBufferFromNativeWindow();
4304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
4305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4306c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                if (info != NULL) {
4307609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                    ALOGV("[%s] calling fillBuffer %u",
4308c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                         mCodec->mComponentName.c_str(), info->mBufferID);
4309349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4310c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
4311c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                             (status_t)OK);
4312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4313c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4314c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                }
4315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
4322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
4324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
4325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4332f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::UninitializedState::UninitializedState(ACodec *codec)
4333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4336c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::UninitializedState::stateEntered() {
4337c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("Now uninitialized");
4338ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4339ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (mDeathNotifier != NULL) {
4340ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mCodec->mOMX->asBinder()->unlinkToDeath(mDeathNotifier);
4341ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
4342ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
4343ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4344ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNativeWindow.clear();
4345ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNode = NULL;
4346ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mOMX.clear();
4347ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mQuirks = 0;
4348ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mFlags = 0;
4349308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    mCodec->mUseMetadataOnEncoderOutput = 0;
4350ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mComponentName.clear();
4351c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4352c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4353f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
4354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatSetup:
4358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onSetup(msg);
4360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
43655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case ACodec::kWhatAllocateComponent:
43665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
43675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            onAllocateComponent(msg);
43685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            handled = true;
43695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
43705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
43715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatShutdown:
4373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4374c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
4375c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
4376c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
437754b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            ALOGW_IF(keepComponentAllocated,
437854b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar                     "cannot keep component allocated on shutdown in Uninitialized state");
4379c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4381d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
4382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
4383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4385c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
4386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatFlush:
4389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4391d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
4392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
4393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4395c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
4396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
4400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4405f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::UninitializedState::onSetup(
4406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4407c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (onAllocateComponent(msg)
4408c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            && mCodec->mLoadedState->onConfigureComponent(msg)) {
4409c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mLoadedState->onStart();
4410c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
44115778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
44125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4413c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
44145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onAllocateComponent");
44155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4416c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    CHECK(mCodec->mNode == NULL);
44175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMXClient client;
4419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(client.connect(), (status_t)OK);
4420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<IOMX> omx = client.interface();
4422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4423ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec->id());
4424ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4425ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mDeathNotifier = new DeathNotifier(notify);
4426ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (omx->asBinder()->linkToDeath(mDeathNotifier) != OK) {
4427ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // This was a local binder, if it dies so do we, we won't care
4428ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // about any notifications in the afterlife.
4429ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
4430ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
4431ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4432e671207115fac3914134c61b336d5fa0242c68caAndreas Huber    Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs;
44335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    AString mime;
4435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
44365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString componentName;
4437d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint32_t quirks = 0;
44387791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen    int32_t encoder = false;
44395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findString("componentName", &componentName)) {
4440e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        ssize_t index = matchingCodecs.add();
4441e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        OMXCodec::CodecNameAndQuirks *entry = &matchingCodecs.editItemAt(index);
4442e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        entry->mName = String8(componentName.c_str());
4443afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
4444e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        if (!OMXCodec::findCodecQuirks(
4445e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                    componentName.c_str(), &entry->mQuirks)) {
4446e671207115fac3914134c61b336d5fa0242c68caAndreas Huber            entry->mQuirks = 0;
4447afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
44485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
44495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(msg->findString("mime", &mime));
44505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
44515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("encoder", &encoder)) {
44525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder = false;
44535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
44545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
44555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMXCodec::findMatchingCodecs(
44565778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mime.c_str(),
44575778822d86b0337407514b9372562b86edfa91cdAndreas Huber                encoder, // createEncoder
44585778822d86b0337407514b9372562b86edfa91cdAndreas Huber                NULL,  // matchComponentName
44595778822d86b0337407514b9372562b86edfa91cdAndreas Huber                0,     // flags
4460e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                &matchingCodecs);
44615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
44621065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
44631065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    sp<CodecObserver> observer = new CodecObserver;
44641065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    IOMX::node_id node = NULL;
44651065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
44661065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
44671065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            ++matchIndex) {
4468e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        componentName = matchingCodecs.itemAt(matchIndex).mName.string();
4469e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        quirks = matchingCodecs.itemAt(matchIndex).mQuirks;
4470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4471078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        pid_t tid = androidGetTid();
4472078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        int prevPriority = androidGetThreadPriority(tid);
4473078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
44741065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        status_t err = omx->allocateNode(componentName.c_str(), observer, &node);
4475078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, prevPriority);
4476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
44771065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        if (err == OK) {
44781065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            break;
44797a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He        } else {
44807a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He            ALOGW("Allocating component '%s' failed, try next one.", componentName.c_str());
44811065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
44821065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
44831065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        node = NULL;
44841065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    }
44851065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
4486c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    if (node == NULL) {
44875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!mime.empty()) {
44887791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen            ALOGE("Unable to instantiate a %scoder for type '%s'.",
44897791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen                    encoder ? "en" : "de", mime.c_str());
44905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
44917791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen            ALOGE("Unable to instantiate codec '%s'.", componentName.c_str());
44925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
4493c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
4494cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        mCodec->signalError(OMX_ErrorComponentNotFound);
4495c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
4496c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
4497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4498ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    notify = new AMessage(kWhatOMXMessage, mCodec->id());
4499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    observer->setNotificationMessage(notify);
4500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mComponentName = componentName;
4502ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    mCodec->mFlags = 0;
4503ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
4504ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (componentName.endsWith(".secure")) {
4505ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        mCodec->mFlags |= kFlagIsSecure;
45060167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
4507ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
4508ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
4509afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mCodec->mQuirks = quirks;
4510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mOMX = omx;
4511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mNode = node;
4512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
45135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
45145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
4515d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatComponentAllocated);
45165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setString("componentName", mCodec->mComponentName.c_str());
45175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
45185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4519c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4520c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mCodec->changeState(mCodec->mLoadedState);
4521c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4522c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
45235778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
45245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4525c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
4526c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4527c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas HuberACodec::LoadedState::LoadedState(ACodec *codec)
4528c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    : BaseState(codec) {
4529c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4530c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4531c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::stateEntered() {
4532c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
4533c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4534f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mPortEOS[kPortIndexInput] =
4535f6f38287b97ec69b169387add6458f859b770e65Andreas Huber        mCodec->mPortEOS[kPortIndexOutput] = false;
4536f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
4537f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mInputEOSResult = OK;
4538f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
4539054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mDequeueCounter = 0;
4540054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mMetaDataBuffersToSubmit = 0;
4541a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    mCodec->mRepeatFrameDelayUs = -1ll;
4542e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mInputFormat.clear();
4543e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mOutputFormat.clear();
4544054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4545c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (mCodec->mShutdownInProgress) {
4546c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
4547c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4548c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mShutdownInProgress = false;
4549c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mKeepComponentAllocated = false;
4550c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4551c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        onShutdown(keepComponentAllocated);
4552c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
455354b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    mCodec->mExplicitShutdown = false;
4554c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4555c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4556c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
4557c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (!keepComponentAllocated) {
4558c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK);
4559c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4560c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->changeState(mCodec->mUninitializedState);
4561c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
4562c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
456354b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    if (mCodec->mExplicitShutdown) {
456454b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        sp<AMessage> notify = mCodec->mNotify->dup();
4565d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
456654b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        notify->post();
456754b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        mCodec->mExplicitShutdown = false;
456854b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    }
4569c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4570c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4571c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
4572c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool handled = false;
4573c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4574c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    switch (msg->what()) {
4575c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatConfigureComponent:
4576c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
4577c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onConfigureComponent(msg);
4578c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
4579c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
4580c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
4581c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
45827cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
45837cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
45847cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            onCreateInputSurface(msg);
45857cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
45867cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
45877cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
45887cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4589c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatStart:
4590c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
4591c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onStart();
4592c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
4593c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
4594c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
4595c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4596c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatShutdown:
4597c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
4598c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
4599c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
4600c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
4601c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
460254b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
4603c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onShutdown(keepComponentAllocated);
4604c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4605c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
4606c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
4607c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
4608c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4609c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatFlush:
4610c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
4611c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4612d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
4613c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->post();
4614c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4615c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
4616c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
4617c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
4618c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4619c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        default:
4620c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            return BaseState::onMessageReceived(msg);
4621c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
4622c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4623c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return handled;
4624c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4625c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4626c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onConfigureComponent(
46275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg) {
46285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onConfigureComponent");
46295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
46305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(mCodec->mNode != NULL);
46315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
46325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString mime;
46335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findString("mime", &mime));
46345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
46355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mCodec->configureCodec(mime.c_str(), msg);
46365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
46375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
4638c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        ALOGE("[%s] configureCodec returning error %d",
4639c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber              mCodec->mComponentName.c_str(), err);
4640c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber
4641251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
4642c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
46435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<RefBase> obj;
4646386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    if (msg->findObject("native-window", &obj)
46475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            && strncmp("OMX.google.", mCodec->mComponentName.c_str(), 11)) {
46481173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        sp<NativeWindowWrapper> nativeWindow(
46491173118eace0e9e347cb007f0da817cee87579edGlenn Kasten                static_cast<NativeWindowWrapper *>(obj.get()));
46501173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        CHECK(nativeWindow != NULL);
46511173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        mCodec->mNativeWindow = nativeWindow->getNativeWindow();
46521ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber
46531ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber        native_window_set_scaling_mode(
46541ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                mCodec->mNativeWindow.get(),
46551ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
4656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((status_t)OK, mCodec->initNativeWindow());
4658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
46595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
46605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
4661d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatComponentConfigured);
4662e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("input-format", mCodec->mInputFormat);
4663e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("output-format", mCodec->mOutputFormat);
46645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
46655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4666c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4667c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
46685778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
46695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
46707cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::LoadedState::onCreateInputSurface(
4671ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        const sp<AMessage> & /* msg */) {
46727cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    ALOGV("onCreateInputSurface");
46737cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
46747cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<AMessage> notify = mCodec->mNotify->dup();
4675d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatInputSurfaceCreated);
46767cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
46777cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<IGraphicBufferProducer> bufferProducer;
46787cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    status_t err;
46797cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
46807cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    err = mCodec->mOMX->createInputSurface(mCodec->mNode, kPortIndexInput,
46817cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            &bufferProducer);
4682a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
4683a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    if (err == OK && mCodec->mRepeatFrameDelayUs > 0ll) {
4684a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        err = mCodec->mOMX->setInternalOption(
4685a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                mCodec->mNode,
4686a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                kPortIndexInput,
4687a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY,
4688a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                &mCodec->mRepeatFrameDelayUs,
4689a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                sizeof(mCodec->mRepeatFrameDelayUs));
4690a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
4691a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (err != OK) {
4692a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            ALOGE("[%s] Unable to configure option to repeat previous "
4693a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  "frames (err %d)",
4694a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  mCodec->mComponentName.c_str(),
4695a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  err);
4696a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
4697a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
4698a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
46992c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    if (err == OK && mCodec->mMaxPtsGapUs > 0ll) {
470094ee4b708acfa941581160b267afb79192b1d816Chong Zhang        err = mCodec->mOMX->setInternalOption(
470194ee4b708acfa941581160b267afb79192b1d816Chong Zhang                mCodec->mNode,
470294ee4b708acfa941581160b267afb79192b1d816Chong Zhang                kPortIndexInput,
470394ee4b708acfa941581160b267afb79192b1d816Chong Zhang                IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP,
470494ee4b708acfa941581160b267afb79192b1d816Chong Zhang                &mCodec->mMaxPtsGapUs,
470594ee4b708acfa941581160b267afb79192b1d816Chong Zhang                sizeof(mCodec->mMaxPtsGapUs));
470694ee4b708acfa941581160b267afb79192b1d816Chong Zhang
470794ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (err != OK) {
470894ee4b708acfa941581160b267afb79192b1d816Chong Zhang            ALOGE("[%s] Unable to configure max timestamp gap (err %d)",
470972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    mCodec->mComponentName.c_str(),
471072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    err);
47112c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
47122c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
47132c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
47142c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    if (err == OK && mCodec->mTimePerCaptureUs > 0ll
47152c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            && mCodec->mTimePerFrameUs > 0ll) {
47162c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        int64_t timeLapse[2];
47172c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[0] = mCodec->mTimePerFrameUs;
47182c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[1] = mCodec->mTimePerCaptureUs;
47192c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        err = mCodec->mOMX->setInternalOption(
47202c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                mCodec->mNode,
47212c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                kPortIndexInput,
47222c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                IOMX::INTERNAL_OPTION_TIME_LAPSE,
47232c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                &timeLapse[0],
47242c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                sizeof(timeLapse));
47252c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
47262c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (err != OK) {
47272c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            ALOGE("[%s] Unable to configure time lapse (err %d)",
47282c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    mCodec->mComponentName.c_str(),
47292c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    err);
47302c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
47312c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
473272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
473372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (err == OK && mCodec->mCreateInputBuffersSuspended) {
473472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        bool suspend = true;
473572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        err = mCodec->mOMX->setInternalOption(
473672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                mCodec->mNode,
473772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                kPortIndexInput,
473872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                IOMX::INTERNAL_OPTION_SUSPEND,
473972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                &suspend,
474072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                sizeof(suspend));
474172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
474272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
474372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("[%s] Unable to configure option to suspend (err %d)",
474494ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  mCodec->mComponentName.c_str(),
474594ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  err);
474694ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
474794ee4b708acfa941581160b267afb79192b1d816Chong Zhang    }
474894ee4b708acfa941581160b267afb79192b1d816Chong Zhang
47497cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err == OK) {
47507cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setObject("input-surface",
47517cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                new BufferProducerWrapper(bufferProducer));
47527cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else {
47537cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // Can't use mCodec->signalError() here -- MediaCodec won't forward
47547cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // the error through because it's in the "configured" state.  We
47557cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // send a kWhatInputSurfaceCreated with an error value instead.
47567cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGE("[%s] onCreateInputSurface returning error %d",
47577cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                mCodec->mComponentName.c_str(), err);
47587cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setInt32("err", err);
47597cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
47607cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->post();
47617cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
47627cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4763c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onStart() {
47645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onStart");
47655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
47665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ(mCodec->mOMX->sendCommand(
47675778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
4768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
4769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->changeState(mCodec->mLoadedToIdleState);
4771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4775f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
4776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4779f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::LoadedToIdleState::stateEntered() {
47803856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
4781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4782cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    status_t err;
4783cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    if ((err = allocateBuffers()) != OK) {
478429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to allocate buffers after transitioning to IDLE state "
4785cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             "(error 0x%08x)",
4786cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             err);
4787cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
4788251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
478991bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber
479091bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber        mCodec->changeState(mCodec->mLoadedState);
4791cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    }
4792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4794f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::LoadedToIdleState::allocateBuffers() {
4795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
4796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
4798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
4799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mCodec->allocateBuffersOnPort(kPortIndexOutput);
4802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4804f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
4805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
480672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
4807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
48136507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
48146507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
48156507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
48166507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
48176507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
48186507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
48196463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatResume:
48206463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
48216463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We'll be active soon enough.
48226463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
48236463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
48246463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
48256463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatFlush:
48266463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
48276463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We haven't even started yet, so we're flushed alright...
48286463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            sp<AMessage> notify = mCodec->mNotify->dup();
4829d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
48306463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->post();
48316463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
48326463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
48336463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
4834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
4836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4839f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onOMXEvent(
4840f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
4846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
4848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting),
4849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
4850f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mIdleToExecutingState);
4852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4863f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
4864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4867f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToExecutingState::stateEntered() {
48683856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
4869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4871f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
4872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
487372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
4874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4880d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatResume:
4881d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
4882d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We'll be active soon enough.
4883d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
4884d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
4885d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
4886d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatFlush:
4887d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
4888d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We haven't even started yet, so we're flushed alright...
4889d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4890d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
4891d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->post();
4892d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
4893d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
4894d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
4895d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
48966507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
48976507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
48986507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
48996507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
49006507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
49016507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
4902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
4904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4907f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onOMXEvent(
4908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateExecuting);
4914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mExecutingState->resume();
4916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingState);
4917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4928f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingState::ExecutingState(ACodec *codec)
4929349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    : BaseState(codec),
4930349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber      mActive(false) {
4931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4933f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
4934ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
4935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
4936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4938054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputMetaBuffers() {
4939054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // submit as many buffers as there are input buffers with the codec
4940054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // in case we are in port reconfiguring
4941054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
4942054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
4943054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4944054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) {
4945054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            if (mCodec->submitOutputMetaDataBuffer() != OK)
4946054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                break;
4947054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
4948054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
49494dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
49504dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
49514dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
4952054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
4953054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4954054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitRegularOutputBuffers() {
4955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
4956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
4957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mCodec->mNativeWindow != NULL) {
4959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(info->mStatus == BufferInfo::OWNED_BY_US
4960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
4961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                continue;
4964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
4966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
4967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
49693856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] calling fillBuffer %p",
4970349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str(), info->mBufferID);
4971349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
4973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
4974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4979054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputBuffers() {
4980c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar    submitRegularOutputBuffers();
4981054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mCodec->mStoreMetaDataInOutputBuffers) {
4982054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        submitOutputMetaBuffers();
4983054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
4984054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
4985054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4986f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::resume() {
4987349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    if (mActive) {
49883856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] We're already active, no need to resume.",
4989349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str());
4990349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4991349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        return;
4992349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    }
4993349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    submitOutputBuffers();
4995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
49963cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    // Post all available input buffers
4997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_GT(mCodec->mBuffers[kPortIndexInput].size(), 0u);
49983cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); i++) {
49993cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
50003cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_US) {
50013cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar            postFillThisBuffer(info);
50023cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        }
50033cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    }
5004349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5005349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    mActive = true;
5006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5008f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::stateEntered() {
50093856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
5010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->processDeferredMessages();
5012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5014f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
5015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5020c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
5021c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
5022c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
5023c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5024c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mShutdownInProgress = true;
502554b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
5026c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mKeepComponentAllocated = keepComponentAllocated;
5027c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5028349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
5029349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
5031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
5032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
5033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingToIdleState);
5035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
50427a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong            ALOGV("[%s] ExecutingState flushing now "
5043d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                 "(codec owns %d/%d input, %d/%d output).",
5044d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mComponentName.c_str(),
5045d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
5046d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexInput].size(),
5047d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
5048d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexOutput].size());
5049d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
5050349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
5051349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
5053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandFlush, OMX_ALL),
5054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
5055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mFlushingState);
5057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatResume:
5062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            resume();
5064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5069496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
5070496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
5071496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            status_t err = mCodec->requestIDRFrame();
5072496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            if (err != OK) {
5073496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                ALOGW("Requesting an IDR frame failed.");
5074496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            }
5075496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5076496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            handled = true;
5077496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
5078496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
5079496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5080a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
5081a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
5082a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
5083a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
5084a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5085a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = mCodec->setParameters(params);
5086a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5087a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> reply;
5088a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            if (msg->findMessage("reply", &reply)) {
5089a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->setInt32("err", err);
5090a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->post();
5091a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            }
5092a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5093a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            handled = true;
5094a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
5095a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
5096a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
50977cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
50987cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
50996507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
51007cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
51017cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
51027cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
51037cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
51044dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
51054dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        case kWhatSubmitOutputMetaDataBufferIfEOS:
51064dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        {
51074dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            if (mCodec->mPortEOS[kPortIndexInput] &&
51084dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    !mCodec->mPortEOS[kPortIndexOutput]) {
51094dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                status_t err = mCodec->submitOutputMetaDataBuffer();
51104dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                if (err == OK) {
51114dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
51124dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                }
51134dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            }
51144dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            return true;
51154dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        }
51164dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
5117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5125a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t ACodec::setParameters(const sp<AMessage> &params) {
5126a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    int32_t videoBitrate;
5127530fdbdc1b5491f3fbf172752834d1515701e142Lajos Molnar    if (params->findInt32("video-bitrate", &videoBitrate)) {
5128a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        OMX_VIDEO_CONFIG_BITRATETYPE configParams;
5129a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        InitOMXParams(&configParams);
5130a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nPortIndex = kPortIndexOutput;
5131a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nEncodeBitrate = videoBitrate;
5132a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5133a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        status_t err = mOMX->setConfig(
5134a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                mNode,
5135a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                OMX_IndexConfigVideoBitrate,
5136a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                &configParams,
5137a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                sizeof(configParams));
5138a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5139a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        if (err != OK) {
5140a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
5141a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                   videoBitrate, err);
5142a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5143a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            return err;
5144a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
5145a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    }
5146a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
514772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    int64_t skipFramesBeforeUs;
514872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (params->findInt64("skip-frames-before", &skipFramesBeforeUs)) {
514972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        status_t err =
515072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mOMX->setInternalOption(
515172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     mNode,
515272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     kPortIndexInput,
515372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     IOMX::INTERNAL_OPTION_START_TIME,
515472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     &skipFramesBeforeUs,
515572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     sizeof(skipFramesBeforeUs));
515672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
515772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
515872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("Failed to set parameter 'skip-frames-before' (err %d)", err);
515972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            return err;
516072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
516172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
516272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
5163e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    int32_t dropInputFrames;
5164e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    if (params->findInt32("drop-input-frames", &dropInputFrames)) {
5165e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        bool suspend = dropInputFrames != 0;
5166e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
5167b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err =
5168b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            mOMX->setInternalOption(
5169e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     mNode,
5170e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     kPortIndexInput,
5171e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     IOMX::INTERNAL_OPTION_SUSPEND,
5172e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     &suspend,
5173b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber                     sizeof(suspend));
5174b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
5175b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
5176b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err);
5177b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
5178b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
5179b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    }
5180b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
5181b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    int32_t dummy;
5182b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    if (params->findInt32("request-sync", &dummy)) {
5183b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err = requestIDRFrame();
5184b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
5185b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
5186b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Requesting a sync frame failed w/ err %d", err);
5187b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
5188b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
5189e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    }
5190e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
5191a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return OK;
5192a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
5193a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
51946507d14c6d10f93d390de62b9eed267f9b544985Andy McFaddenvoid ACodec::onSignalEndOfInputStream() {
51956507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    sp<AMessage> notify = mNotify->dup();
5196d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatSignaledInputEOS);
51976507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
51986507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    status_t err = mOMX->signalEndOfInputStream(mNode);
51996507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    if (err != OK) {
52006507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        notify->setInt32("err", err);
52016507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    }
52026507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->post();
52036507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden}
52046507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
5205f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onOMXEvent(
5206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventPortSettingsChanged:
5209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
5211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
521231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
5213054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mCodec->mMetaDataBuffersToSubmit = 0;
5214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
5215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
5216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_CommandPortDisable, kPortIndexOutput),
5217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
5218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5219349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                mCodec->freeOutputBuffersNotOwnedByComponent();
5220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
522231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            } else if (data2 == OMX_IndexConfigCommonOutputCrop) {
522331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
5224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
52253856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08lx",
5226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->mComponentName.c_str(), data2);
5227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventBufferFlag:
5233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5244f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
5245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ACodec *codec)
5246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5249f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
5250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
5251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput) {
5252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return FREE_BUFFERS;
5253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
5256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
5258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5260f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onMessageReceived(
5261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
5262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5267349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case kWhatResume:
5268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5269349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            if (msg->what() == kWhatResume) {
52703856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
5271349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            }
5272349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
5274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5286f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::OutputPortSettingsChangedState::stateEntered() {
52873856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now handling output port settings change",
5288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mCodec->mComponentName.c_str());
5289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5291f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onOMXEvent(
5292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
5297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
5298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
52993856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now disabled.",
5300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
5301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mCodec->mBuffers[kPortIndexOutput].isEmpty());
5303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mDealer[kPortIndexOutput].clear();
5304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
5306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput),
5307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
5308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5309cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                status_t err;
5310cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                if ((err = mCodec->allocateBuffersOnPort(
5311cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                                kPortIndexOutput)) != OK) {
531229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("Failed to allocate output port buffers after "
5313cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         "port reconfiguration (error 0x%08x)",
5314cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         err);
5315cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
5316251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5317d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
5318755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // This is technically not correct, but appears to be
5319755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the only way to free the component instance.
5320755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // Controlled transitioning from excecuting->idle
5321755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // and idle->loaded seem impossible probably because
5322755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the output port never finishes re-enabling.
5323755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mShutdownInProgress = true;
5324755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mKeepComponentAllocated = false;
5325755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->changeState(mCodec->mLoadedState);
5326cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                }
5327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
5329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
5330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
5331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
533231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
533331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
53343856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now reenabled.",
5335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
5336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5337349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                if (mCodec->mExecutingState->active()) {
5338349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    mCodec->mExecutingState->submitOutputBuffers();
5339349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                }
5340349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mExecutingState);
5342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
5344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
5347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
5351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5356f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
53575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : BaseState(codec),
53585778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mComponentNowIdle(false) {
5359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5361f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
5362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
5368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
5369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
5370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
5376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5389f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::stateEntered() {
53903856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
539131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
53925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mComponentNowIdle = false;
539331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mCodec->mSentFormat = false;
5394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5396f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onOMXEvent(
5397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
5402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
5403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
54045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mComponentNowIdle = true;
54055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            changeStateIfWeOwnAllBuffers();
5407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5411349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
5412349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventBufferFlag:
5413349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
5414349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We're shutting down and don't care about this anymore.
5415349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
5416349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
5417349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
54220af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
5423f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
54245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
5425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->sendCommand(
5426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded),
5427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
5428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexInput), (status_t)OK);
5430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexOutput), (status_t)OK);
5431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
54320167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown)
54330167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && mCodec->mNativeWindow != NULL) {
5434bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // We push enough 1x1 blank buffers to ensure that one of
5435bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // them has made it to the display.  This allows the OMX
5436bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // component teardown to zero out any protected buffers
5437bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // without the risk of scanning out one of those buffers.
5438bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            mCodec->pushBlankBuffersToNativeWindow();
5439bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
5440bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
5441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mIdleToLoadedState);
5442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5445f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onInputBufferFilled(
5446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
5447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
5448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
5450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5452f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onOutputBufferDrained(
5453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
5454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
5455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
5457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5461f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
5462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5465f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
5466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
5472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
5480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
5481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
5482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5493f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToLoadedState::stateEntered() {
54943856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
5495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5497f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onOMXEvent(
5498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
5503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateLoaded);
5504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5505c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->changeState(mCodec->mLoadedState);
5506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5517f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::FlushingState::FlushingState(ACodec *codec)
5518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5521f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::stateEntered() {
55223856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
5523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
5525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5527f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
5528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
5534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing this right now.
5540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5552f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onOMXEvent(
5553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
55547a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] FlushingState onOMXEvent(%d,%ld)",
5555d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            mCodec->mComponentName.c_str(), event, data1);
5556d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
5557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandFlush);
5561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
5563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(!mFlushComplete[data2]);
5564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mFlushComplete[data2] = true;
5565e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber
5566e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                if (mFlushComplete[kPortIndexInput]
5567e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                        && mFlushComplete[kPortIndexOutput]) {
5568e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                    changeStateIfWeOwnAllBuffers();
5569e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                }
5570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
5571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, OMX_ALL);
5572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexInput]);
5573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexOutput]);
5574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                changeStateIfWeOwnAllBuffers();
5576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5581349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
5582349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
5583349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec->id());
5584349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("type", omx_message::EVENT);
5585609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            msg->setInt32("node", mCodec->mNode);
5586349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("event", event);
5587349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data1", data1);
5588349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data2", data2);
5589349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
55903856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
5591349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                 mCodec->mComponentName.c_str());
5592349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5593349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mCodec->deferMessage(msg);
5594349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5595349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
5596349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
5597349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
5603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5605f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
5606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
5607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
5609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5611f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
5612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
5613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
5615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5617f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
5618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mFlushComplete[kPortIndexInput]
5619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mFlushComplete[kPortIndexOutput]
5620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mCodec->allYourBuffersAreBelongToUs()) {
56217e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // We now own all buffers except possibly those still queued with
56227e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // the native window for rendering. Let's get those back as well.
56237e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
56247e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
5625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
5626d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatFlushCompleted);
5627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->post();
5628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->mPortEOS[kPortIndexInput] =
5630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mPortEOS[kPortIndexOutput] = false;
5631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5632dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber        mCodec->mInputEOSResult = OK;
5633dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
5634f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        if (mCodec->mSkipCutBuffer != NULL) {
5635f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen            mCodec->mSkipCutBuffer->clear();
5636f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        }
5637f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen
5638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mExecutingState);
5639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
5643