ACodec.cpp revision e6eea3a6b6e0cf92287ec1ceb8350f201d17e1ac
127c174483a8ae9688d5d4897c19074f62c7f1701James Dong/*
227c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Copyright (C) 2010 The Android Open Source Project
327c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
427c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Licensed under the Apache License, Version 2.0 (the "License");
527c174483a8ae9688d5d4897c19074f62c7f1701James Dong * you may not use this file except in compliance with the License.
627c174483a8ae9688d5d4897c19074f62c7f1701James Dong * You may obtain a copy of the License at
727c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
827c174483a8ae9688d5d4897c19074f62c7f1701James Dong *      http://www.apache.org/licenses/LICENSE-2.0
927c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
1027c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Unless required by applicable law or agreed to in writing, software
1127c174483a8ae9688d5d4897c19074f62c7f1701James Dong * distributed under the License is distributed on an "AS IS" BASIS,
1227c174483a8ae9688d5d4897c19074f62c7f1701James Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1327c174483a8ae9688d5d4897c19074f62c7f1701James Dong * See the License for the specific language governing permissions and
1427c174483a8ae9688d5d4897c19074f62c7f1701James Dong * limitations under the License.
1527c174483a8ae9688d5d4897c19074f62c7f1701James Dong */
1627c174483a8ae9688d5d4897c19074f62c7f1701James Dong
17f933441648ef6a71dee783d733aac17b9508b452Andreas Huber//#define LOG_NDEBUG 0
18f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#define LOG_TAG "ACodec"
19f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
20f87e30fe71752dc431d8e8d5682c38271c03265aAndy Hung#ifdef __LP64__
21f87e30fe71752dc431d8e8d5682c38271c03265aAndy Hung#define OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
22f87e30fe71752dc431d8e8d5682c38271c03265aAndy Hung#endif
23f87e30fe71752dc431d8e8d5682c38271c03265aAndy Hung
24609b815a3131d22da38b2f452faa9f89daad4039Andy Hung#include <inttypes.h>
256fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar#include <utils/Trace.h>
266fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar
27f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/ACodec.h>
28f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
29f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <binder/MemoryDealer.h>
30f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/hexdump.h>
32f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ABuffer.h>
33f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ADebug.h>
34f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/AMessage.h>
35a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar#include <media/stagefright/foundation/AUtils.h>
36f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
377cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden#include <media/stagefright/BufferProducerWrapper.h>
38afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber#include <media/stagefright/MediaCodecList.h>
39f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaDefs.h>
401173118eace0e9e347cb007f0da817cee87579edGlenn Kasten#include <media/stagefright/NativeWindowWrapper.h>
41f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/OMXClient.h>
421065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber#include <media/stagefright/OMXCodec.h>
43f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
443a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber#include <media/hardware/HardwareAPI.h>
453a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
4697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu#include <OMX_AudioExt.h>
474154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev#include <OMX_VideoExt.h>
48f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <OMX_Component.h>
4997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu#include <OMX_IndexExt.h>
50f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
51496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#include "include/avc_utils.h"
52496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
53f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android {
54f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
55251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// OMX errors are directly mapped into status_t range if
56251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// there is no corresponding MediaError status code.
57251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Use the statusFromOMXError(int32_t omxError) function.
58251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung//
59251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Currently this is a direct map.
60251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// See frameworks/native/include/media/openmax/OMX_Core.h
61251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung//
62251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Vendor OMX errors     from 0x90000000 - 0x9000FFFF
63251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Extension OMX errors  from 0x8F000000 - 0x90000000
64251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Standard OMX errors   from 0x80001000 - 0x80001024 (0x80001024 current)
65251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung//
66251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
67251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// returns true if err is a recognized OMX error code.
68251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// as OMX error is OMX_S32, this is an int32_t type
69251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hungstatic inline bool isOMXError(int32_t err) {
70251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    return (ERROR_CODEC_MIN <= err && err <= ERROR_CODEC_MAX);
71251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung}
72251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
73251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// converts an OMX error to a status_t
74251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hungstatic inline status_t statusFromOMXError(int32_t omxError) {
75251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    switch (omxError) {
76251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case OMX_ErrorInvalidComponentName:
77251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case OMX_ErrorComponentNotFound:
78251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return NAME_NOT_FOUND; // can trigger illegal argument error for provided names.
79251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    default:
80251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return isOMXError(omxError) ? omxError : 0; // no translation required
81251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
82251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung}
83251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
84251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// checks and converts status_t to a non-side-effect status_t
85251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hungstatic inline status_t makeNoSideEffectStatus(status_t err) {
86251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    switch (err) {
87251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // the following errors have side effects and may come
88251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // from other code modules. Remap for safety reasons.
89251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case INVALID_OPERATION:
90251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case DEAD_OBJECT:
91251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return UNKNOWN_ERROR;
92251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    default:
93251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return err;
94251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
95251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung}
96251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
97f933441648ef6a71dee783d733aac17b9508b452Andreas Hubertemplate<class T>
98f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic void InitOMXParams(T *params) {
99f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nSize = sizeof(T);
100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nVersionMajor = 1;
101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nVersionMinor = 0;
102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nRevision = 0;
103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nStep = 0;
104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
106f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct CodecObserver : public BnOMXObserver {
107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CodecObserver() {}
108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void setNotificationMessage(const sp<AMessage> &msg) {
110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mNotify = msg;
111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // from IOMXObserver
114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onMessage(const omx_message &omx_msg) {
115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> msg = mNotify->dup();
116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->setInt32("type", omx_msg.type);
118609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        msg->setInt32("node", omx_msg.node);
119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        switch (omx_msg.type) {
121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::EVENT:
122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("event", omx_msg.u.event_data.event);
124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("data1", omx_msg.u.event_data.data1);
125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("data2", omx_msg.u.event_data.data2);
126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::EMPTY_BUFFER_DONE:
130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
131609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                msg->setInt32("buffer", omx_msg.u.buffer_data.buffer);
132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::FILL_BUFFER_DONE:
136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
137609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                msg->setInt32(
138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "buffer", omx_msg.u.extended_buffer_data.buffer);
139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "range_offset",
141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.range_offset);
142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "range_length",
144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.range_length);
145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "flags",
147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.flags);
148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt64(
149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "timestamp",
150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.timestamp);
151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            default:
155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                TRESPASS();
156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->post();
160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
162f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual ~CodecObserver() {}
164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
165f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> mNotify;
167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(CodecObserver);
169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
173f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::BaseState : public AState {
174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState(ACodec *codec, const sp<AState> &parentState = NULL);
175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
176f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    enum PortMode {
178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        KEEP_BUFFERS,
179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        RESUBMIT_BUFFERS,
180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        FREE_BUFFERS,
181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ACodec *mCodec;
184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void postFillThisBuffer(BufferInfo *info);
195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
196f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXMessage(const sp<AMessage> &msg);
198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXEmptyBufferDone(IOMX::buffer_id bufferID);
200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXFillBufferDone(
202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID,
203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            size_t rangeOffset, size_t rangeLength,
204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            OMX_U32 flags,
205784e24e386b088c05d653ab482f2e95cb53e3d01Andy Hung            int64_t timeUs);
206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void getMoreInputDataIfPossible();
208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(BaseState);
210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
214ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberstruct ACodec::DeathNotifier : public IBinder::DeathRecipient {
215ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    DeathNotifier(const sp<AMessage> &notify)
216ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        : mNotify(notify) {
217ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
218ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
219ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual void binderDied(const wp<IBinder> &) {
220ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mNotify->post();
221ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
222ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
223ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprotected:
224ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual ~DeathNotifier() {}
225ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
226ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprivate:
227ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> mNotify;
228ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
229ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(DeathNotifier);
230ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber};
231ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
232f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::UninitializedState : public ACodec::BaseState {
233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    UninitializedState(ACodec *codec);
234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
235f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
237c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
239f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void onSetup(const sp<AMessage> &msg);
241c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onAllocateComponent(const sp<AMessage> &msg);
242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
243ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<DeathNotifier> mDeathNotifier;
244ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(UninitializedState);
246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
250c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberstruct ACodec::LoadedState : public ACodec::BaseState {
251c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    LoadedState(ACodec *codec);
252c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
253c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprotected:
254c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
255c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
256c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
257c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprivate:
258c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    friend struct ACodec::UninitializedState;
259c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
260c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onConfigureComponent(const sp<AMessage> &msg);
2617cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    void onCreateInputSurface(const sp<AMessage> &msg);
262c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onStart();
263c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onShutdown(bool keepComponentAllocated);
264c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
265c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedState);
266c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber};
267c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
268c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
269c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
270f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::LoadedToIdleState : public ACodec::BaseState {
271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    LoadedToIdleState(ACodec *codec);
272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
273f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
278f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t allocateBuffers();
280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedToIdleState);
282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
286f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToExecutingState : public ACodec::BaseState {
287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToExecutingState(ACodec *codec);
288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
289f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
294f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToExecutingState);
296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
300f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingState : public ACodec::BaseState {
301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingState(ACodec *codec);
302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
303054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitRegularOutputBuffers();
304054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitOutputMetaBuffers();
305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void submitOutputBuffers();
306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Submit output buffers to the decoder, submit input buffers to client
308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // to fill with data.
309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void resume();
310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
311349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    // Returns true iff input and output buffers are in play.
312349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool active() const { return mActive; }
313349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
314f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
321f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
322349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool mActive;
323349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingState);
325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
329f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::OutputPortSettingsChangedState : public ACodec::BaseState {
330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OutputPortSettingsChangedState(ACodec *codec);
331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
332f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
339f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(OutputPortSettingsChangedState);
341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
345f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingToIdleState : public ACodec::BaseState {
346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingToIdleState(ACodec *codec);
347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
348f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
357f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool mComponentNowIdle;
3615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingToIdleState);
363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
367f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToLoadedState : public ACodec::BaseState {
368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToLoadedState(ACodec *codec);
369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
370f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
376f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToLoadedState);
378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
382f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::FlushingState : public ACodec::BaseState {
383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    FlushingState(ACodec *codec);
384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
385f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
394f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool mFlushComplete[2];
396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(FlushingState);
400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
404f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ACodec()
405afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    : mQuirks(0),
406609b815a3131d22da38b2f452faa9f89daad4039Andy Hung      mNode(0),
4075778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mSentFormat(false),
408c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber      mIsEncoder(false),
409308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang      mUseMetadataOnEncoderOutput(false),
4109806555d3930be43e11106281dee354820ac1c88Andreas Huber      mShutdownInProgress(false),
41154b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar      mExplicitShutdown(false),
4129806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderDelay(0),
4139806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderPadding(0),
414e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang      mRotationDegrees(0),
4159806555d3930be43e11106281dee354820ac1c88Andreas Huber      mChannelMaskPresent(false),
416054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mChannelMask(0),
417054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mDequeueCounter(0),
418054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mStoreMetaDataInOutputBuffers(false),
419a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber      mMetaDataBuffersToSubmit(0),
42094ee4b708acfa941581160b267afb79192b1d816Chong Zhang      mRepeatFrameDelayUs(-1ll),
4212c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang      mMaxPtsGapUs(-1ll),
4222c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang      mTimePerFrameUs(-1ll),
423609b815a3131d22da38b2f452faa9f89daad4039Andy Hung      mTimePerCaptureUs(-1ll),
424ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad      mCreateInputBuffersSuspended(false),
425ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad      mTunneled(false) {
426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mUninitializedState = new UninitializedState(this);
427c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mLoadedState = new LoadedState(this);
428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mLoadedToIdleState = new LoadedToIdleState(this);
429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToExecutingState = new IdleToExecutingState(this);
430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingState = new ExecutingState(this);
431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOutputPortSettingsChangedState =
433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        new OutputPortSettingsChangedState(this);
434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingToIdleState = new ExecutingToIdleState(this);
436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToLoadedState = new IdleToLoadedState(this);
437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushingState = new FlushingState(this);
438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
440dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber    mInputEOSResult = OK;
441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeState(mUninitializedState);
443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
445f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::~ACodec() {
446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
448f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::setNotificationMessage(const sp<AMessage> &msg) {
449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mNotify = msg;
450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
452f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::initiateSetup(const sp<AMessage> &msg) {
453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setWhat(kWhatSetup);
454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setTarget(id());
455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
458a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Hubervoid ACodec::signalSetParameters(const sp<AMessage> &params) {
459a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    sp<AMessage> msg = new AMessage(kWhatSetParameters, id());
460a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->setMessage("params", params);
461a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->post();
462a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
463a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4645778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateAllocateComponent(const sp<AMessage> &msg) {
4655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatAllocateComponent);
4665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
4675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4685778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4705778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateConfigureComponent(const sp<AMessage> &msg) {
4715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatConfigureComponent);
4725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
4735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4745778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4767cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::initiateCreateInputSurface() {
4777cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    (new AMessage(kWhatCreateInputSurface, id()))->post();
4787cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
4797cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4807cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::signalEndOfInputStream() {
4817cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    (new AMessage(kWhatSignalEndOfInputStream, id()))->post();
4827cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
4837cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4845778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateStart() {
4855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    (new AMessage(kWhatStart, id()))->post();
4865778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
488f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalFlush() {
4897a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] signalFlush", mComponentName.c_str());
490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatFlush, id()))->post();
491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
493f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalResume() {
494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatResume, id()))->post();
495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
497c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::initiateShutdown(bool keepComponentAllocated) {
498c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> msg = new AMessage(kWhatShutdown, id());
499c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->setInt32("keepComponentAllocated", keepComponentAllocated);
500c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->post();
501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
503496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubervoid ACodec::signalRequestIDRFrame() {
504496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    (new AMessage(kWhatRequestIDRFrame, id()))->post();
505496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
506496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5074dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
5084dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// Some codecs may return input buffers before having them processed.
5094dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// This causes a halt if we already signaled an EOS on the input
5104dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// port.  For now keep submitting an output buffer if there was an
5114dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// EOS on the input port, but not yet on the output port.
5124dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnarvoid ACodec::signalSubmitOutputMetaDataBufferIfEOS_workaround() {
5134dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    if (mPortEOS[kPortIndexInput] && !mPortEOS[kPortIndexOutput] &&
5144dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            mMetaDataBuffersToSubmit > 0) {
5154dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        (new AMessage(kWhatSubmitOutputMetaDataBufferIfEOS, id()))->post();
5164dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    }
5174dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar}
5184dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
519f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mDealer[portIndex] == NULL);
523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mBuffers[portIndex].isEmpty());
524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
527054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (mStoreMetaDataInOutputBuffers) {
528054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputMetaDataBuffers();
529054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
530054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputBuffersFromNativeWindow();
531054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
5325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
5335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
5345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
5355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = portIndex;
536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
5385778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err == OK) {
541609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGV("[%s] Allocating %u buffers of size %u on %s port",
5425778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mComponentName.c_str(),
5435778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    def.nBufferCountActual, def.nBufferSize,
5445778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    portIndex == kPortIndexInput ? "input" : "output");
545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            size_t totalSize = def.nBufferCountActual * def.nBufferSize;
5475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
5505778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
5515778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(mem.get() != NULL);
552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
553ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                BufferInfo info;
554ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                info.mStatus = BufferInfo::OWNED_BY_US;
555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
556afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                uint32_t requiresAllocateBufferBit =
557afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                    (portIndex == kPortIndexInput)
558afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        ? OMXCodec::kRequiresAllocateBufferOnInputPorts
559afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        : OMXCodec::kRequiresAllocateBufferOnOutputPorts;
5601065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
561308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                if ((portIndex == kPortIndexInput && (mFlags & kFlagIsSecure))
562308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        || mUseMetadataOnEncoderOutput) {
563ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    mem.clear();
564ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
565ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    void *ptr;
566ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->allocateBuffer(
567ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, def.nBufferSize, &info.mBufferID,
568ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            &ptr);
569ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
570308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    int32_t bufSize = mUseMetadataOnEncoderOutput ?
571308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                            (4 + sizeof(buffer_handle_t)) : def.nBufferSize;
572308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
573308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    info.mData = new ABuffer(ptr, bufSize);
574ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                } else if (mQuirks & requiresAllocateBufferBit) {
5755778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    err = mOMX->allocateBufferWithBackup(
576ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, mem, &info.mBufferID);
5775778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
578ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->useBuffer(mNode, portIndex, mem, &info.mBufferID);
579ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                }
580ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
581ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                if (mem != NULL) {
582ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    info.mData = new ABuffer(mem->pointer(), def.nBufferSize);
5835778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
5841065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
5855778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mBuffers[portIndex].push(info);
5861065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            }
5871065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
5885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
5915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
5925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> notify = mNotify->dup();
595d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatBuffersAllocated);
5965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("portIndex", portIndex);
598eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
599eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    sp<PortDescription> desc = new PortDescription;
600eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
6015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
602eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        const BufferInfo &info = mBuffers[portIndex][i];
6035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
604eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        desc->addBuffer(info.mBufferID, info.mData);
605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
607eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    notify->setObject("portDesc", desc);
6085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->post();
6095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
613054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::configureOutputBuffersFromNativeWindow(
614054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 *bufferCount, OMX_U32 *bufferSize,
615054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 *minUndequeuedBuffers) {
616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = kPortIndexOutput;
619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffers_geometry(
628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameWidth,
630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameHeight,
631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.eColorFormat);
632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
63429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffers_geometry failed: %s (%d)",
635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                strerror(-err), -err);
636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
639e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang    if (mRotationDegrees != 0) {
640e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        uint32_t transform = 0;
641e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        switch (mRotationDegrees) {
642e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            case 0: transform = 0; break;
643e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            case 90: transform = HAL_TRANSFORM_ROT_90; break;
644e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            case 180: transform = HAL_TRANSFORM_ROT_180; break;
645e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            case 270: transform = HAL_TRANSFORM_ROT_270; break;
646e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            default: transform = 0; break;
647e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        }
648e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang
649e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        if (transform > 0) {
650e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            err = native_window_set_buffers_transform(
651e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang                    mNativeWindow.get(), transform);
652e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            if (err != 0) {
653e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang                ALOGE("native_window_set_buffers_transform failed: %s (%d)",
654e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang                        strerror(-err), -err);
655e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang                return err;
656e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            }
657e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        }
658e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang    }
659e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang
660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Set up the native window.
6613c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    OMX_U32 usage = 0;
6623c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
6633c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    if (err != 0) {
6645ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("querying usage flags from OMX IL component failed: %d", err);
6653c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        // XXX: Currently this error is logged, but not fatal.
6663c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        usage = 0;
6673c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    }
6683c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis
669bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (mFlags & kFlagIsSecure) {
670bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        usage |= GRALLOC_USAGE_PROTECTED;
671bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
672bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
673bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // Make sure to check whether either Stagefright or the video decoder
674bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // requested protected buffers.
675bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (usage & GRALLOC_USAGE_PROTECTED) {
676bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Verify that the ANativeWindow sends images directly to
677bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // SurfaceFlinger.
678bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        int queuesToNativeWindow = 0;
679bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->query(
680bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                mNativeWindow.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
681bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                &queuesToNativeWindow);
682bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != 0) {
683bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error authenticating native window: %d", err);
684bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
685bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
686bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (queuesToNativeWindow != 1) {
687bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("native window could not be authenticated");
688bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return PERMISSION_DENIED;
689bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
690bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
691bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_usage(
693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
6943c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis            usage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP);
695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
69729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err);
698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
701ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // Exits here for tunneled video playback codecs -- i.e. skips native window
702ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // buffer allocation step as this is managed by the tunneled OMX omponent
703ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // itself and explicitly sets def.nBufferCountActual to 0.
704ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    if (mTunneled) {
705ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        ALOGV("Tunneled Playback: skipping native window buffer allocation.");
706ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        def.nBufferCountActual = 0;
707ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        err = mOMX->setParameter(
708ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
709ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
710ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *minUndequeuedBuffers = 0;
711ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *bufferCount = 0;
712ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *bufferSize = 0;
713ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        return err;
714ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    }
715ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
716054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *minUndequeuedBuffers = 0;
717258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    err = mNativeWindow->query(
718258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
719054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (int *)minUndequeuedBuffers);
720258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
721258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    if (err != 0) {
72229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
723258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                strerror(-err), -err);
724258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        return err;
725258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
726258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
727e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // FIXME: assume that surface is controlled by app (native window
728e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // returns the number for the case when surface is not controlled by app)
7291faa41704e0b976e546321effcb09a85767d51baLajos Molnar    // FIXME2: This means that minUndeqeueudBufs can be 1 larger than reported
7301faa41704e0b976e546321effcb09a85767d51baLajos Molnar    // For now, try to allocate 1 more buffer, but don't fail if unsuccessful
731e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar
732e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // Use conservative allocation while also trying to reduce starvation
733e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //
734e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // 1. allocate at least nBufferCountMin + minUndequeuedBuffers - that is the
735e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //    minimum needed for the consumer to be able to work
736e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // 2. try to allocate two (2) additional buffers to reduce starvation from
737e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //    the consumer
7381faa41704e0b976e546321effcb09a85767d51baLajos Molnar    //    plus an extra buffer to account for incorrect minUndequeuedBufs
7391faa41704e0b976e546321effcb09a85767d51baLajos Molnar    for (OMX_U32 extraBuffers = 2 + 1; /* condition inside loop */; extraBuffers--) {
740e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        OMX_U32 newBufferCount =
741e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            def.nBufferCountMin + *minUndequeuedBuffers + extraBuffers;
742258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        def.nBufferCountActual = newBufferCount;
743258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        err = mOMX->setParameter(
744258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
745258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
746e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        if (err == OK) {
747e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            *minUndequeuedBuffers += extraBuffers;
748e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            break;
749e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        }
750e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar
751609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGW("[%s] setting nBufferCountActual to %u failed: %d",
752e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar                mComponentName.c_str(), newBufferCount, err);
753e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        /* exit condition */
754e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        if (extraBuffers == 0) {
755258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            return err;
756258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        }
757258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
758258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffer_count(
760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(), def.nBufferCountActual);
761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
76329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                -err);
765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
768054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferCount = def.nBufferCountActual;
769054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferSize =  def.nBufferSize;
770054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
771054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
772054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
773054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputBuffersFromNativeWindow() {
774054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
775054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
776054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
777054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
778054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
779e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    mNumUndequeuedBuffers = minUndequeuedBuffers;
780054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
781609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Allocating %u buffers from a native window of size %u on "
782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         "output port",
783054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount, bufferSize);
784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Dequeue buffers and send them to OMX
786054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
7878ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev        ANativeWindowBuffer *buf;
7881e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
79029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
79574006804065941841883c4b46ee785070164023fJamie Gennis        BufferInfo info;
79674006804065941841883c4b46ee785070164023fJamie Gennis        info.mStatus = BufferInfo::OWNED_BY_US;
797054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(NULL /* data */, bufferSize /* capacity */);
79874006804065941841883c4b46ee785070164023fJamie Gennis        info.mGraphicBuffer = graphicBuffer;
79974006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].push(info);
80074006804065941841883c4b46ee785070164023fJamie Gennis
801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferId;
802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &bufferId);
804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
805609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGE("registering GraphicBuffer %u with OMX IL component failed: "
80674006804065941841883c4b46ee785070164023fJamie Gennis                 "%d", i, err);
807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
81074006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
81174006804065941841883c4b46ee785070164023fJamie Gennis
812609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGV("[%s] Registered graphic buffer with ID %u (pointer = %p)",
813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mComponentName.c_str(),
814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             bufferId, graphicBuffer.get());
815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelStart;
818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelEnd;
819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // If an error occurred while dequeuing we need to cancel any buffers
822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // that were dequeued.
823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelStart = 0;
82474006804065941841883c4b46ee785070164023fJamie Gennis        cancelEnd = mBuffers[kPortIndexOutput].size();
825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
826054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // Return the required minimum undequeued buffers to the native window.
827054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelStart = bufferCount - minUndequeuedBuffers;
828054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelEnd = bufferCount;
829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
8333fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        status_t error = cancelBufferToNativeWindow(info);
8343fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        if (err == 0) {
8353fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia            err = error;
8363fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        }
837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
840f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
842054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputMetaDataBuffers() {
843054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
844054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
845054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
846054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
847054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
848e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    mNumUndequeuedBuffers = minUndequeuedBuffers;
849054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
850609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Allocating %u meta buffers on output port",
851054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount);
852054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
853054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    size_t totalSize = bufferCount * 8;
854054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mDealer[kPortIndexOutput] = new MemoryDealer(totalSize, "ACodec");
855054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
856054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // Dequeue buffers and send them to OMX
857054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
858054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo info;
859054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
860054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mGraphicBuffer = NULL;
861054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mDequeuedAt = mDequeueCounter;
862054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
863054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        sp<IMemory> mem = mDealer[kPortIndexOutput]->allocate(
864054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                sizeof(struct VideoDecoderOutputMetaData));
865054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(mem.get() != NULL);
866054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(mem->pointer(), mem->size());
867054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
868054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // we use useBuffer for metadata regardless of quirks
869054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        err = mOMX->useBuffer(
870054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mNode, kPortIndexOutput, mem, &info.mBufferID);
871054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
872054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        mBuffers[kPortIndexOutput].push(info);
873054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
874609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGV("[%s] allocated meta buffer with ID %u (pointer = %p)",
875054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mComponentName.c_str(), info.mBufferID, mem->pointer());
876054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
877054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
878054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mMetaDataBuffersToSubmit = bufferCount - minUndequeuedBuffers;
879054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
880054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
881054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
882054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::submitOutputMetaDataBuffer() {
883054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mStoreMetaDataInOutputBuffers);
884054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mMetaDataBuffersToSubmit == 0)
885054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return OK;
886054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
887054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *info = dequeueBufferFromNativeWindow();
888054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (info == NULL)
889054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return ERROR_IO;
890054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
891609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] submitting output meta buffer ID %u for graphic buffer %p",
892054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          mComponentName.c_str(), info->mBufferID, info->mGraphicBuffer.get());
893054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
894054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    --mMetaDataBuffersToSubmit;
895054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK_EQ(mOMX->fillBuffer(mNode, info->mBufferID),
896054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             (status_t)OK);
897054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
898054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
899054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return OK;
900054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
901054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
902f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
905609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Calling cancelBuffer on buffer %u",
906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mComponentName.c_str(), info->mBufferID);
907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int err = mNativeWindow->cancelBuffer(
9091e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        mNativeWindow.get(), info->mGraphicBuffer.get(), -1);
910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9113fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia    ALOGW_IF(err != 0, "[%s] can not return buffer %u to native window",
9123fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia            mComponentName.c_str(), info->mBufferID);
913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9163fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia    return err;
917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
919f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
9208ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev    ANativeWindowBuffer *buf;
9211e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    int fenceFd = -1;
922054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mNativeWindow.get() != NULL);
923ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
924ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    if (mTunneled) {
925ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        ALOGW("dequeueBufferFromNativeWindow() should not be called in tunnel"
926ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad              " video playback mode mode!");
927ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        return NULL;
928ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    }
929ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
9301e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    if (native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf) != 0) {
93129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("dequeueBuffer failed.");
932c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber        return NULL;
933c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
935054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *oldest = NULL;
936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
940054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mGraphicBuffer != NULL &&
941054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            info->mGraphicBuffer->handle == buf->handle) {
942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus,
943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (int)BufferInfo::OWNED_BY_NATIVE_WINDOW);
944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
949054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
950054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW &&
951054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (oldest == NULL ||
952054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             // avoid potential issues from counter rolling over
953054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mDequeueCounter - info->mDequeuedAt >
954054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    mDequeueCounter - oldest->mDequeuedAt)) {
955054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            oldest = info;
956054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
957054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
958054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
959054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (oldest) {
960054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(mStoreMetaDataInOutputBuffers);
961054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
962054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // discard buffer in LRU info and replace with new buffer
963054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mGraphicBuffer = new GraphicBuffer(buf, false);
964054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mStatus = BufferInfo::OWNED_BY_US;
965054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
966d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        mOMX->updateGraphicBufferInMeta(
967d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                mNode, kPortIndexOutput, oldest->mGraphicBuffer,
968d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                oldest->mBufferID);
969054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
970d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        VideoDecoderOutputMetaData *metaData =
971d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar            reinterpret_cast<VideoDecoderOutputMetaData *>(
972d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                    oldest->mData->base());
973d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        CHECK_EQ(metaData->eType, kMetadataBufferTypeGrallocSource);
974d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar
975d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
976054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                oldest - &mBuffers[kPortIndexOutput][0],
977054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mDequeueCounter - oldest->mDequeuedAt,
978d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                metaData->pHandle,
979d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                oldest->mGraphicBuffer->handle, oldest->mData->base());
980054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
981054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return oldest;
982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
989f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[portIndex].size(); i-- > 0;) {
991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, freeBuffer(portIndex, i));
992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDealer[portIndex].clear();
995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
999349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huberstatus_t ACodec::freeOutputBuffersNotOwnedByComponent() {
1000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
1001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
1002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
1003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10042ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // At this time some buffers may still be with the component
10052ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // or being drained.
10062ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT &&
10072ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar            info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) {
1008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK, freeBuffer(kPortIndexOutput, i));
1009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1015f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
1016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
1017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(info->mStatus == BufferInfo::OWNED_BY_US
1019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
1020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput && mNativeWindow != NULL
1022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && info->mStatus == BufferInfo::OWNED_BY_US) {
10233fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        cancelBufferToNativeWindow(info);
1024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(mOMX->freeBuffer(
1027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, portIndex, info->mBufferID),
1028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
1029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mBuffers[portIndex].removeAt(i);
1031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1035f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::findBufferByID(
1036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        uint32_t portIndex, IOMX::buffer_id bufferID,
1037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ssize_t *index) {
1038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
1039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
1040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mBufferID == bufferID) {
1042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (index != NULL) {
1043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                *index = i;
1044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
1046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
1050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
1052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10545778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setComponentRole(
1055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        bool isEncoder, const char *mime) {
1056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    struct MimeToRole {
1057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime;
1058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *decoderRole;
1059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *encoderRole;
1060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
1061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const MimeToRole kMimeToRole[] = {
1063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG,
1064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.mp3", "audio_encoder.mp3" },
10652944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
10662944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp1", "audio_encoder.mp1" },
10672944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
10682944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp2", "audio_encoder.mp2" },
1069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_NB,
1070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrnb", "audio_encoder.amrnb" },
1071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_WB,
1072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrwb", "audio_encoder.amrwb" },
1073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AAC,
1074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.aac", "audio_encoder.aac" },
1075729de186450f78c099637e1fce743fe531862c52Andreas Huber        { MEDIA_MIMETYPE_AUDIO_VORBIS,
1076729de186450f78c099637e1fce743fe531862c52Andreas Huber            "audio_decoder.vorbis", "audio_encoder.vorbis" },
1077bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian        { MEDIA_MIMETYPE_AUDIO_OPUS,
1078bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian            "audio_decoder.opus", "audio_encoder.opus" },
1079c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_MLAW,
1080c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" },
1081c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_ALAW,
1082c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711alaw", "audio_encoder.g711alaw" },
1083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_AVC,
1084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.avc", "video_encoder.avc" },
10852472b1c0d63454e5d90a982bd6c555de6c3127bdRachad        { MEDIA_MIMETYPE_VIDEO_HEVC,
10862472b1c0d63454e5d90a982bd6c555de6c3127bdRachad            "video_decoder.hevc", "video_encoder.hevc" },
1087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_MPEG4,
1088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.mpeg4", "video_encoder.mpeg4" },
1089f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_H263,
1090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.h263", "video_encoder.h263" },
109194705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP8,
109294705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp8", "video_encoder.vp8" },
109394705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP9,
109494705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp9", "video_encoder.vp9" },
1095ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        { MEDIA_MIMETYPE_AUDIO_RAW,
1096ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            "audio_decoder.raw", "audio_encoder.raw" },
10972f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        { MEDIA_MIMETYPE_AUDIO_FLAC,
10982f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            "audio_decoder.flac", "audio_encoder.flac" },
1099ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        { MEDIA_MIMETYPE_AUDIO_MSGSM,
1100ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen            "audio_decoder.gsm", "audio_encoder.gsm" },
1101774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu        { MEDIA_MIMETYPE_VIDEO_MPEG2,
1102774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu            "video_decoder.mpeg2", "video_encoder.mpeg2" },
110397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        { MEDIA_MIMETYPE_AUDIO_AC3,
110497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            "audio_decoder.ac3", "audio_encoder.ac3" },
1105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
1106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const size_t kNumMimeToRole =
1108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
1109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    size_t i;
1111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (i = 0; i < kNumMimeToRole; ++i) {
1112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcasecmp(mime, kMimeToRole[i].mime)) {
1113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (i == kNumMimeToRole) {
11185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_UNSUPPORTED;
1119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    const char *role =
1122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        isEncoder ? kMimeToRole[i].encoderRole
1123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                  : kMimeToRole[i].decoderRole;
1124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (role != NULL) {
1126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_PARAM_COMPONENTROLETYPE roleParams;
1127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        InitOMXParams(&roleParams);
1128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        strncpy((char *)roleParams.cRole,
1130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                role, OMX_MAX_STRINGNAME_SIZE - 1);
1131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
1133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->setParameter(
1135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamStandardComponentRole,
1136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &roleParams, sizeof(roleParams));
1137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
11395ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("[%s] Failed to set standard component role '%s'.",
1140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 mComponentName.c_str(), role);
11415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
1143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
11455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
1147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
11495778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::configureCodec(
1150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime, const sp<AMessage> &msg) {
11515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t encoder;
11525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("encoder", &encoder)) {
11535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        encoder = false;
11545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1156e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    sp<AMessage> inputFormat = new AMessage();
1157e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    sp<AMessage> outputFormat = new AMessage();
1158e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
11595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mIsEncoder = encoder;
1160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
11615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setComponentRole(encoder /* isEncoder */, mime);
11625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
11645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
11655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
11665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitRate = 0;
11682f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    // FLAC encoder doesn't need a bitrate, other encoders do
11692f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
11702f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            && !msg->findInt32("bitrate", &bitRate)) {
11715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
11725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
11735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1174d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    int32_t storeMeta;
1175d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (encoder
1176d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && msg->findInt32("store-metadata-in-buffers", &storeMeta)
1177d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && storeMeta != 0) {
1178d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE);
1179d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1180d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (err != OK) {
1181308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              ALOGE("[%s] storeMetaDataInBuffers (input) failed w/ err %d",
1182308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    mComponentName.c_str(), err);
1183d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1184308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              return err;
1185308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang          }
1186308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang      }
1187d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1188308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t prependSPSPPS = 0;
11893a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    if (encoder
11903a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
11913a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && prependSPSPPS != 0) {
11923a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        OMX_INDEXTYPE index;
11933a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        err = mOMX->getExtensionIndex(
11943a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                mNode,
11953a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                "OMX.google.android.index.prependSPSPPSToIDRFrames",
11963a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                &index);
11973a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
11983a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err == OK) {
11993a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            PrependSPSPPSToIDRFramesParams params;
12003a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            InitOMXParams(&params);
12013a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            params.bEnable = OMX_TRUE;
12023a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
12033a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            err = mOMX->setParameter(
12043a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                    mNode, index, &params, sizeof(params));
12053a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
12063a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
12073a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err != OK) {
12083a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            ALOGE("Encoder could not be configured to emit SPS/PPS before "
12093a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                  "IDR frames. (err %d)", err);
12103a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
12113a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            return err;
12123a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
12133a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    }
12143a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
1215308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // Only enable metadata mode on encoder output if encoder can prepend
1216308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // sps/pps to idr frames, since in metadata mode the bitstream is in an
1217308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // opaque handle, to which we don't have access.
1218308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t video = !strncasecmp(mime, "video/", 6);
1219308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (encoder && video) {
1220308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS
1221308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && msg->findInt32("store-metadata-in-buffers-output", &storeMeta)
1222308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && storeMeta != 0);
1223308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1224308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, enable);
1225308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1226308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        if (err != OK) {
1227308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            ALOGE("[%s] storeMetaDataInBuffers (output) failed w/ err %d",
1228308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                mComponentName.c_str(), err);
1229308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = 0;
1230308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        } else {
1231308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = enable;
1232308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        }
1233a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
1234a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (!msg->findInt64(
1235a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    "repeat-previous-frame-after",
1236a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    &mRepeatFrameDelayUs)) {
1237a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            mRepeatFrameDelayUs = -1ll;
1238a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
123994ee4b708acfa941581160b267afb79192b1d816Chong Zhang
124094ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (!msg->findInt64("max-pts-gap-to-encoder", &mMaxPtsGapUs)) {
12412c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mMaxPtsGapUs = -1ll;
12422c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
12432c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
12442c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (!msg->findInt64("time-lapse", &mTimePerCaptureUs)) {
12452c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mTimePerCaptureUs = -1ll;
124694ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
124772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
124872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (!msg->findInt32(
124972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    "create-input-buffers-suspended",
125072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    (int32_t*)&mCreateInputBuffersSuspended)) {
125172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mCreateInputBuffersSuspended = false;
125272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
1253308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    }
1254308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1255054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    sp<RefBase> obj;
1256054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    int32_t haveNativeWindow = msg->findObject("native-window", &obj) &&
12575a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        obj != NULL;
1258054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mStoreMetaDataInOutputBuffers = false;
1259e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if (video && !encoder) {
1260e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        inputFormat->setInt32("adaptive-playback", false);
1261e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
1262054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (!encoder && video && haveNativeWindow) {
12635a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        sp<NativeWindowWrapper> windowWrapper(
12645a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                static_cast<NativeWindowWrapper *>(obj.get()));
12655a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        sp<ANativeWindow> nativeWindow = windowWrapper->getNativeWindow();
12665a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
12675a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        int32_t tunneled;
12685a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        if (msg->findInt32("feature-tunneled-playback", &tunneled) &&
12695a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            tunneled != 0) {
12705a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            ALOGI("Configuring TUNNELED video playback.");
1271ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            mTunneled = true;
12725a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
127397827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad            int32_t audioHwSync = 0;
127497827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad            if (!msg->findInt32("audio-hw-sync", &audioHwSync)) {
12755a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGW("No Audio HW Sync provided for video tunnel");
12765a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            }
12775a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            err = configureTunneledVideoPlayback(audioHwSync, nativeWindow);
12785a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (err != OK) {
127997827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad                ALOGE("configureTunneledVideoPlayback(%d,%p) failed!",
12805a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        audioHwSync, nativeWindow.get());
12815a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                return err;
1282fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
1283fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
12845a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            inputFormat->setInt32("adaptive-playback", true);
12855a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        } else {
1286ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            ALOGV("Configuring CPU controlled video playback.");
1287ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            mTunneled = false;
1288ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
12895a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            // Always try to enable dynamic output buffers on native surface
12905a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            err = mOMX->storeMetaDataInBuffers(
12915a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    mNode, kPortIndexOutput, OMX_TRUE);
12925a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (err != OK) {
12935a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d",
1294fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        mComponentName.c_str(), err);
1295e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
12965a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // if adaptive playback has been requested, try JB fallback
12975a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // NOTE: THIS FALLBACK MECHANISM WILL BE REMOVED DUE TO ITS
12985a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // LARGE MEMORY REQUIREMENT
12995a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
13005a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // we will not do adaptive playback on software accessed
13015a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // surfaces as they never had to respond to changes in the
13025a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // crop window, and we don't trust that they will be able to.
13035a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                int usageBits = 0;
13045a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                bool canDoAdaptivePlayback;
13055a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
13065a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                if (nativeWindow->query(
13075a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        nativeWindow.get(),
13085a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        NATIVE_WINDOW_CONSUMER_USAGE_BITS,
13095a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        &usageBits) != OK) {
13105a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    canDoAdaptivePlayback = false;
13115a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                } else {
13125a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    canDoAdaptivePlayback =
13135a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        (usageBits &
13145a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                                (GRALLOC_USAGE_SW_READ_MASK |
13155a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                                 GRALLOC_USAGE_SW_WRITE_MASK)) == 0;
13165a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                }
13175a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
13185a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                int32_t maxWidth = 0, maxHeight = 0;
13195a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                if (canDoAdaptivePlayback &&
13205a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        msg->findInt32("max-width", &maxWidth) &&
13215a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        msg->findInt32("max-height", &maxHeight)) {
13225a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    ALOGV("[%s] prepareForAdaptivePlayback(%dx%d)",
13235a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mComponentName.c_str(), maxWidth, maxHeight);
13245a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
13255a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    err = mOMX->prepareForAdaptivePlayback(
13265a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mNode, kPortIndexOutput, OMX_TRUE, maxWidth,
13275a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            maxHeight);
13285a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    ALOGW_IF(err != OK,
13295a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            "[%s] prepareForAdaptivePlayback failed w/ err %d",
13305a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mComponentName.c_str(), err);
13315a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
13325a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    if (err == OK) {
13335a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("max-width", maxWidth);
13345a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("max-height", maxHeight);
13355a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("adaptive-playback", true);
13365a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    }
1337e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
13385a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // allow failure
13395a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                err = OK;
13405a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            } else {
13415a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGV("[%s] storeMetaDataInBuffers succeeded",
13425a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        mComponentName.c_str());
13435a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                mStoreMetaDataInOutputBuffers = true;
13445a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                inputFormat->setInt32("adaptive-playback", true);
1345fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
13460167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber
13475a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            int32_t push;
13485a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (msg->findInt32("push-blank-buffers-on-shutdown", &push)
13495a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    && push != 0) {
13505a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
13515a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            }
13520167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        }
1353e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang
1354e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        int32_t rotationDegrees;
1355e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        if (msg->findInt32("rotation-degrees", &rotationDegrees)) {
1356e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            mRotationDegrees = rotationDegrees;
1357e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        } else {
1358e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            mRotationDegrees = 0;
1359e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        }
1360054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1361054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1362308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (video) {
13635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (encoder) {
13645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupVideoEncoder(mime, msg);
13655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
136689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            err = setupVideoDecoder(mime, msg);
13675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
136842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
136942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        int32_t numChannels, sampleRate;
137042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        if (!msg->findInt32("channel-count", &numChannels)
137142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
137242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // Since we did not always check for these, leave them optional
137342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // and have the decoder figure it all out.
137442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = OK;
137542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        } else {
137642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = setupRawAudioFormat(
137742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    encoder ? kPortIndexInput : kPortIndexOutput,
137842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    sampleRate,
137942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    numChannels);
138042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        }
1381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
1382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t numChannels, sampleRate;
13835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)
13845778822d86b0337407514b9372562b86edfa91cdAndreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
13855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
13865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
1387aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            int32_t isADTS, aacProfile;
1388b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            int32_t sbrMode;
13898045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            int32_t maxOutputChannelCount;
13902965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            int32_t pcmLimiterEnable;
13918045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            drcParams_t drc;
1392ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            if (!msg->findInt32("is-adts", &isADTS)) {
1393ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                isADTS = 0;
1394ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
1395aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (!msg->findInt32("aac-profile", &aacProfile)) {
1396aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                aacProfile = OMX_AUDIO_AACObjectNull;
1397aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
1398b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            if (!msg->findInt32("aac-sbr-mode", &sbrMode)) {
1399b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                sbrMode = -1;
1400b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            }
1401ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
14028045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-max-output-channel_count", &maxOutputChannelCount)) {
14038045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                maxOutputChannelCount = -1;
14048045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
14052965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            if (!msg->findInt32("aac-pcm-limiter-enable", &pcmLimiterEnable)) {
14062965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                // value is unknown
14072965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                pcmLimiterEnable = -1;
14082965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            }
14098045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-encoded-target-level", &drc.encodedTargetLevel)) {
14108045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
14118045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.encodedTargetLevel = -1;
14128045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
14138045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-cut-level", &drc.drcCut)) {
14148045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
14158045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.drcCut = -1;
14168045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
14178045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-boost-level", &drc.drcBoost)) {
14188045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
14198045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.drcBoost = -1;
14208045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
14218045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-heavy-compression", &drc.heavyCompression)) {
14228045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
14238045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.heavyCompression = -1;
14248045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
14258045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-target-ref-level", &drc.targetRefLevel)) {
14268045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
14278045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.targetRefLevel = -1;
14288045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
14298045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi
1430ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            err = setupAACCodec(
14314471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    encoder, numChannels, sampleRate, bitRate, aacProfile,
14322965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                    isADTS != 0, sbrMode, maxOutputChannelCount, drc,
14332965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                    pcmLimiterEnable);
14345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
1435729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
14365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
1437729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
14385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
1439729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
1440729de186450f78c099637e1fce743fe531862c52Andreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
1441729de186450f78c099637e1fce743fe531862c52Andreas Huber        // These are PCM-like formats with a fixed sample rate but
1442729de186450f78c099637e1fce743fe531862c52Andreas Huber        // a variable number of channels.
1443729de186450f78c099637e1fce743fe531862c52Andreas Huber
1444729de186450f78c099637e1fce743fe531862c52Andreas Huber        int32_t numChannels;
14455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)) {
14465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
14475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
14485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupG711Codec(encoder, numChannels);
14495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14502f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
14512f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        int32_t numChannels, sampleRate, compressionLevel = -1;
14522f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (encoder &&
14532f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                (!msg->findInt32("channel-count", &numChannels)
14542f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                        || !msg->findInt32("sample-rate", &sampleRate))) {
14552f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("missing channel count or sample rate for FLAC encoder");
14562f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            err = INVALID_OPERATION;
14572f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        } else {
14582f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            if (encoder) {
1459516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                if (!msg->findInt32(
1460cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                            "complexity", &compressionLevel) &&
1461cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                    !msg->findInt32(
1462516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                            "flac-compression-level", &compressionLevel)) {
1463cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                    compressionLevel = 5; // default FLAC compression level
14642f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel < 0) {
1465516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1466516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 0",
1467516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
14682f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 0;
14692f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel > 8) {
1470516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1471516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 8",
1472516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
14732f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 8;
14742f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                }
14752f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            }
1476516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            err = setupFlacCodec(
1477516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    encoder, numChannels, sampleRate, compressionLevel);
14782f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
1479ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
1480ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        int32_t numChannels, sampleRate;
1481ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        if (encoder
1482ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("channel-count", &numChannels)
1483ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
1484ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = INVALID_OPERATION;
1485ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        } else {
1486ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
1487ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        }
148897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AC3)) {
148997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t numChannels;
149097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t sampleRate;
149197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        if (!msg->findInt32("channel-count", &numChannels)
149297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                || !msg->findInt32("sample-rate", &sampleRate)) {
149397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = INVALID_OPERATION;
149497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        } else {
149597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = setupAC3Codec(encoder, numChannels, sampleRate);
149697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        }
14975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1498729de186450f78c099637e1fce743fe531862c52Andreas Huber
14994471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    if (err != OK) {
15004471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber        return err;
15014471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    }
15024471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber
15038b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
15048b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderDelay = 0;
15058b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
15069806555d3930be43e11106281dee354820ac1c88Andreas Huber
15078b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
15088b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderPadding = 0;
15098b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
15108b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen
15119806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (msg->findInt32("channel-mask", &mChannelMask)) {
15129806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = true;
15139806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else {
15149806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = false;
15159806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
15169806555d3930be43e11106281dee354820ac1c88Andreas Huber
1517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t maxInputSize;
1518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (msg->findInt32("max-input-size", &maxInputSize)) {
15195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
1520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
15215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
1522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
15235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1524e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ(getPortFormat(kPortIndexInput, inputFormat), (status_t)OK);
1525e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ(getPortFormat(kPortIndexOutput, outputFormat), (status_t)OK);
1526e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mInputFormat = inputFormat;
1527e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mOutputFormat = outputFormat;
1528e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
15295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
1530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1532f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
1533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
1535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
1536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (def.nBufferSize >= size) {
1545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
1546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nBufferSize = size;
1549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
1551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->getParameter(
1558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(def.nBufferSize >= size);
1565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
15695778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::selectAudioPortFormat(
15705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
15715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_AUDIO_PARAM_PORTFORMATTYPE format;
15725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&format);
15735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    format.nPortIndex = portIndex;
15755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (OMX_U32 index = 0;; ++index) {
15765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        format.nIndex = index;
15775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
15795778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioPortFormat,
15805778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &format, sizeof(format));
15815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
15835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
15845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (format.eEncoding == desiredFormat) {
15875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
15885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
15925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format));
15935778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
15945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15955778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAACCodec(
1596aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        bool encoder, int32_t numChannels, int32_t sampleRate,
15978045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        int32_t bitRate, int32_t aacProfile, bool isADTS, int32_t sbrMode,
15982965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang        int32_t maxOutputChannelCount, const drcParams_t& drc,
15992965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang        int32_t pcmLimiterEnable) {
1600ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (encoder && isADTS) {
1601ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return -EINVAL;
1602ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
1603ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
16045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setupRawAudioFormat(
16055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
16065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sampleRate,
16075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            numChannels);
16085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
16105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
16115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (encoder) {
16145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
16155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
16175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
16185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
16215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
16225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = kPortIndexOutput;
16235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
16255778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
16265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
16285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
16295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.bFlagErrorConcealment = OMX_TRUE;
16325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
16335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
16355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
16365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
16385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
16395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
16425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&profile);
16435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nPortIndex = kPortIndexOutput;
16445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
16465778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
16475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
16495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
16505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nChannels = numChannels;
16535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eChannelMode =
16555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (numChannels == 1)
16565778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
16575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nSampleRate = sampleRate;
16595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nBitRate = bitRate;
16605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAudioBandWidth = 0;
16615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nFrameLength = 0;
16625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACtools = OMX_AUDIO_AACToolAll;
16635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACERtools = OMX_AUDIO_AACERNone;
1664aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
16655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
1666b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        switch (sbrMode) {
1667b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 0:
1668b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // disable sbr
1669b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
1670b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
1671b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
1672b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 1:
1673b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable single-rate sbr
1674b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
1675b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
1676b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
1677b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 2:
1678b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable dual-rate sbr
1679b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
1680b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
1681b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
1682b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case -1:
1683b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable both modes -> the codec will decide which mode should be used
1684b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
1685b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
1686b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
1687b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        default:
1688b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // unsupported sbr mode
1689b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            return BAD_VALUE;
1690b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        }
1691b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi
16925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
16945778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
16955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
16975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
16985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
17015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_AUDIO_PARAM_AACPROFILETYPE profile;
1704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&profile);
1705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nPortIndex = kPortIndexInput;
1706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
17075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
1708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
1709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nChannels = numChannels;
1715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nSampleRate = sampleRate;
1716ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1717ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    profile.eAACStreamFormat =
1718ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        isADTS
1719ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            ? OMX_AUDIO_AACStreamFormatMP4ADTS
1720ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            : OMX_AUDIO_AACStreamFormatMP4FF;
1721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
17228045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    OMX_AUDIO_PARAM_ANDROID_AACPRESENTATIONTYPE presentation;
17238045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nMaxOutputChannels = maxOutputChannelCount;
17248045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nDrcCut = drc.drcCut;
17258045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nDrcBoost = drc.drcBoost;
17268045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nHeavyCompression = drc.heavyCompression;
17278045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nTargetReferenceLevel = drc.targetRefLevel;
17288045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nEncodedTargetLevel = drc.encodedTargetLevel;
17292965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang    presentation.nPCMLimiterEnable = pcmLimiterEnable;
17308045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi
17318045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    status_t res = mOMX->setParameter(mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
17328045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    if (res == OK) {
17338045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        // optional parameters, will not cause configuration failure
17348045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        mOMX->setParameter(mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAacPresentation,
17358045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                &presentation, sizeof(presentation));
17368045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    } else {
17378045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        ALOGW("did not set AudioAndroidAacPresentation due to error %d when setting AudioAac", res);
17388045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    }
17398045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    return res;
17405778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
174297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryustatus_t ACodec::setupAC3Codec(
174397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        bool encoder, int32_t numChannels, int32_t sampleRate) {
174497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    status_t err = setupRawAudioFormat(
174597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
174697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
174797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
174897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
174997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
175097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
175197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (encoder) {
175297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        ALOGW("AC3 encoding is not supported.");
175397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return INVALID_OPERATION;
175497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
175597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
175697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    OMX_AUDIO_PARAM_ANDROID_AC3TYPE def;
175797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    InitOMXParams(&def);
175897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nPortIndex = kPortIndexInput;
175997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
176097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    err = mOMX->getParameter(
176197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
176297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
176397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
176497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
176597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
176697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
176797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
176897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
176997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
177097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nChannels = numChannels;
177197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nSampleRate = sampleRate;
177297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
177397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    return mOMX->setParameter(
177497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
177597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
177697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
177797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
177897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu}
177997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
17805778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
17815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        bool isAMRWB, int32_t bps) {
17825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (isAMRWB) {
17835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 6600) {
17845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB0;
17855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 8850) {
17865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB1;
17875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 12650) {
17885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB2;
17895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 14250) {
17905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB3;
17915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 15850) {
17925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB4;
17935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 18250) {
17945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB5;
17955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 19850) {
17965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB6;
17975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 23050) {
17985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB7;
17995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 23850 bps
18025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeWB8;
18035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {  // AMRNB
18045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 4750) {
18055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB0;
18065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5150) {
18075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB1;
18085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5900) {
18095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB2;
18105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 6700) {
18115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB3;
18125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7400) {
18135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB4;
18145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7950) {
18155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB5;
18165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 10200) {
18175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB6;
18185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 12200 bps
18215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeNB7;
18225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
18255778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
1826729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_AMRTYPE def;
1827729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
18285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
1829729de186450f78c099637e1fce743fe531862c52Andreas Huber
1830729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err =
1831729de186450f78c099637e1fce743fe531862c52Andreas Huber        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1832729de186450f78c099637e1fce743fe531862c52Andreas Huber
1833729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1834729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1835729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1836729de186450f78c099637e1fce743fe531862c52Andreas Huber
1837729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
18385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
18395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
18415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1842729de186450f78c099637e1fce743fe531862c52Andreas Huber
18435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1846729de186450f78c099637e1fce743fe531862c52Andreas Huber
18475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupRawAudioFormat(
18485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
18495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            isWAMR ? 16000 : 8000 /* sampleRate */,
18505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            1 /* numChannels */);
1851729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1852729de186450f78c099637e1fce743fe531862c52Andreas Huber
18535778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupG711Codec(bool encoder, int32_t numChannels) {
18545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(!encoder);  // XXX TODO
18555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1856729de186450f78c099637e1fce743fe531862c52Andreas Huber    return setupRawAudioFormat(
1857729de186450f78c099637e1fce743fe531862c52Andreas Huber            kPortIndexInput, 8000 /* sampleRate */, numChannels);
1858729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1859729de186450f78c099637e1fce743fe531862c52Andreas Huber
18602f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivistatus_t ACodec::setupFlacCodec(
18612f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
18622f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
18632f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder) {
18642f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        OMX_AUDIO_PARAM_FLACTYPE def;
18652f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        InitOMXParams(&def);
18662f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nPortIndex = kPortIndexOutput;
18672f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
18682f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        // configure compression level
18692f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        status_t err = mOMX->getParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
18702f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
18712f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
18722f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
18732f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
18742f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nCompressionLevel = compressionLevel;
18752f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        err = mOMX->setParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
18762f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
18772f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
18782f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
18792f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
18802f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
18812f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
18822f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    return setupRawAudioFormat(
18832f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            encoder ? kPortIndexInput : kPortIndexOutput,
18842f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            sampleRate,
18852f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            numChannels);
18862f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi}
18872f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
1888729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t ACodec::setupRawAudioFormat(
1889729de186450f78c099637e1fce743fe531862c52Andreas Huber        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
1890729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1891729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
1892729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.nPortIndex = portIndex;
1893729de186450f78c099637e1fce743fe531862c52Andreas Huber
1894729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err = mOMX->getParameter(
1895729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1896729de186450f78c099637e1fce743fe531862c52Andreas Huber
1897729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1898729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1899729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1900729de186450f78c099637e1fce743fe531862c52Andreas Huber
1901729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
1902729de186450f78c099637e1fce743fe531862c52Andreas Huber
1903729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->setParameter(
1904729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1905729de186450f78c099637e1fce743fe531862c52Andreas Huber
1906729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1907729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1908729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1909729de186450f78c099637e1fce743fe531862c52Andreas Huber
1910729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
1911729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&pcmParams);
1912729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nPortIndex = portIndex;
1913729de186450f78c099637e1fce743fe531862c52Andreas Huber
1914729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->getParameter(
1915729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1916729de186450f78c099637e1fce743fe531862c52Andreas Huber
1917729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1918729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1919729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1920729de186450f78c099637e1fce743fe531862c52Andreas Huber
1921729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nChannels = numChannels;
1922729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.eNumData = OMX_NumericalDataSigned;
1923729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.bInterleaved = OMX_TRUE;
1924729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nBitPerSample = 16;
1925729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nSamplingRate = sampleRate;
1926729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
1927729de186450f78c099637e1fce743fe531862c52Andreas Huber
1928c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber    if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
1929c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber        return OMX_ErrorNone;
1930729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1931729de186450f78c099637e1fce743fe531862c52Andreas Huber
1932729de186450f78c099637e1fce743fe531862c52Andreas Huber    return mOMX->setParameter(
1933729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1934729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1935729de186450f78c099637e1fce743fe531862c52Andreas Huber
19365a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachadstatus_t ACodec::configureTunneledVideoPlayback(
193797827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad        int32_t audioHwSync, const sp<ANativeWindow> &nativeWindow) {
19385a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    native_handle_t* sidebandHandle;
19395a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
19405a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    status_t err = mOMX->configureVideoTunnelMode(
19415a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            mNode, kPortIndexOutput, OMX_TRUE, audioHwSync, &sidebandHandle);
19425a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    if (err != OK) {
19435a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        ALOGE("configureVideoTunnelMode failed! (err %d).", err);
19445a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        return err;
19455a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    }
19465a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
19475a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    err = native_window_set_sideband_stream(nativeWindow.get(), sidebandHandle);
19485a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    if (err != OK) {
19495a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        ALOGE("native_window_set_sideband_stream(%p) failed! (err %d).",
19505a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                sidebandHandle, err);
19515a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        return err;
19525a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    }
19535a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
19545a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    return OK;
19555a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad}
19565a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
1957f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoPortFormatType(
1958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
1959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_VIDEO_CODINGTYPE compressionFormat,
1960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_COLOR_FORMATTYPE colorFormat) {
1961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
1963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = portIndex;
1964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
1965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool found = false;
1966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 index = 0;
1968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (;;) {
1969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        format.nIndex = index;
1970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->getParameter(
1971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamVideoPortFormat,
1972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &format, sizeof(format));
1973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
1975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return err;
1976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1978229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        // substitute back flexible color format to codec supported format
1979229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        OMX_U32 flexibleEquivalent;
1980229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        if (compressionFormat == OMX_VIDEO_CodingUnused &&
1981229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                isFlexibleColorFormat(
1982229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                        mOMX, mNode, format.eColorFormat, &flexibleEquivalent) &&
1983229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                colorFormat == flexibleEquivalent) {
1984229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            ALOGI("[%s] using color format %#x in place of %#x",
1985229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                    mComponentName.c_str(), format.eColorFormat, colorFormat);
1986229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            colorFormat = format.eColorFormat;
1987229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
1988229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
1989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The following assertion is violated by TI's video decoder.
1990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // CHECK_EQ(format.nIndex, index);
1991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
1993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexInput
1994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && colorFormat == format.eColorFormat) {
1995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eCompressionFormat does not seem right.
1996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
1997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
1998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexOutput
2000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && compressionFormat == format.eCompressionFormat) {
2001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eColorFormat does not seem right.
2002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
2003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
2004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (format.eCompressionFormat == compressionFormat
2008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && format.eColorFormat == colorFormat) {
2009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            found = true;
2010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ++index;
2014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!found) {
2017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return UNKNOWN_ERROR;
2018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->setParameter(
2021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
2022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
2023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
2025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2027f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setSupportedOutputFormat() {
2028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
2029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
2030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = kPortIndexOutput;
2031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
2032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
2034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
2035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
2036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
2037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)format.eCompressionFormat, (int)OMX_VIDEO_CodingUnused);
2038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mOMX->setParameter(
2040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
2041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
2042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2044e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic const struct VideoCodingMapEntry {
2045e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    const char *mMime;
2046e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    OMX_VIDEO_CODINGTYPE mVideoCodingType;
2047e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber} kVideoCodingMapEntry[] = {
2048e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC },
20492472b1c0d63454e5d90a982bd6c555de6c3127bdRachad    { MEDIA_MIMETYPE_VIDEO_HEVC, OMX_VIDEO_CodingHEVC },
2050e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 },
2051e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 },
2052e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 },
205394705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 },
205494705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 },
2055e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber};
2056e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
20575778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic status_t GetVideoCodingTypeFromMime(
20585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
2059e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
2060e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
2061e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
2062e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) {
2063e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *codingType = kVideoCodingMapEntry[i].mVideoCodingType;
2064e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
2065e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
2066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2068e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    *codingType = OMX_VIDEO_CodingUnused;
2069e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2070e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
2071e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
2072e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2073e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic status_t GetMimeTypeForVideoCoding(
2074e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        OMX_VIDEO_CODINGTYPE codingType, AString *mime) {
2075e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
2076e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
2077e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
2078e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) {
2079e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *mime = kVideoCodingMapEntry[i].mMime;
2080e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
2081e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
2082e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
2083e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2084e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    mime->clear();
2085e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2086e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
20875778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
20885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20895778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoDecoder(
209089869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        const char *mime, const sp<AMessage> &msg) {
209189869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    int32_t width, height;
209289869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    if (!msg->findInt32("width", &width)
209389869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            || !msg->findInt32("height", &height)) {
209489869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        return INVALID_OPERATION;
209589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    }
209689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar
20975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
20985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
20995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
2105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
2106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
211189869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    int32_t tmp;
211289869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    if (msg->findInt32("color-format", &tmp)) {
211389869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        OMX_COLOR_FORMATTYPE colorFormat =
211489869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            static_cast<OMX_COLOR_FORMATTYPE>(tmp);
211589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        err = setVideoPortFormatType(
211689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar                kPortIndexOutput, OMX_VIDEO_CodingUnused, colorFormat);
211789869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        if (err != OK) {
211889869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            ALOGW("[%s] does not support color format %d",
211989869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar                  mComponentName.c_str(), colorFormat);
212089869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            err = setSupportedOutputFormat();
212189869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        }
212289869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    } else {
212389869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        err = setSupportedOutputFormat();
212489869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    }
2125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
2131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, width, height, compressionFormat);
2132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
2138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
2139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
21475778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) {
21485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
21495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("color-format", &tmp)) {
21505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
21515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_COLOR_FORMATTYPE colorFormat =
21545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        static_cast<OMX_COLOR_FORMATTYPE>(tmp);
21555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setVideoPortFormatType(
21575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
21585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support color format %d",
21615778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str(), colorFormat);
21625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Input port configuration */
21675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
21695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&def);
21705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
21725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexInput;
21745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
21765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
21775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t width, height, bitrate;
21835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("width", &width)
21845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("height", &height)
21855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("bitrate", &bitrate)) {
21865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
21875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
21905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
21915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t stride;
21935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("stride", &stride)) {
21945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        stride = width;
21955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nStride = stride;
21985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t sliceHeight;
22005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("slice-height", &sliceHeight)) {
22015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sliceHeight = height;
22025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nSliceHeight = sliceHeight;
22055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
22075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
22095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
22105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
22115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
22125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
22135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
22152c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        mTimePerFrameUs = (int64_t) (1000000.0f / frameRate);
22165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
22195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
22205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = colorFormat;
22215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
22235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
22245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set input port definition parameters.",
22275778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
22285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Output port configuration */
22335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
22355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
22365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
22425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
22435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support compression format %d",
22465778822d86b0337407514b9372562b86edfa91cdAndreas Huber             mComponentName.c_str(), compressionFormat);
22475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexOutput;
22525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
22545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
22555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
22615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
22625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = 0;
22635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nBitrate = bitrate;
22645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = compressionFormat;
22655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = OMX_COLOR_FormatUnused;
22665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
22685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
22695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set output port definition parameters.",
22725778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
22735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (compressionFormat) {
22785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingMPEG4:
22795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupMPEG4EncoderParameters(msg);
22805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
22815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingH263:
22835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupH263EncoderParameters(msg);
22845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
22855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingAVC:
22875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupAVCEncoderParameters(msg);
22885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
22895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2290c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        case OMX_VIDEO_CodingHEVC:
2291c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            err = setupHEVCEncoderParameters(msg);
2292c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            break;
2293c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
229489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP8:
229589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP9:
229689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            err = setupVPXEncoderParameters(msg);
229789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            break;
229889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
22995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
23005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
23015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGI("setupVideoEncoder succeeded");
23045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
23065778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
23075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23080dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dongstatus_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) {
23090dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    OMX_VIDEO_PARAM_INTRAREFRESHTYPE params;
23100dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    InitOMXParams(&params);
23110dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.nPortIndex = kPortIndexOutput;
23120dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
23130dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode);
23140dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
23150dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic ||
23160dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
23170dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
23180dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) {
23190dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
23200dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
23210dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nCirMBs = mbs;
23220dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
23230dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
23240dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive ||
23250dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
23260dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
23270dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) {
23280dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
23290dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
23300dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirMBs = mbs;
23310dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
23320dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t ref;
23330dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) {
23340dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
23350dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
23360dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirRef = ref;
23370dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
23380dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
23390dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = mOMX->setParameter(
23400dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            mNode, OMX_IndexParamVideoIntraRefresh,
23410dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            &params, sizeof(params));
23420dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    return err;
23430dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong}
23440dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
23455778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
23465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (iFramesInterval < 0) {
23475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0xFFFFFFFF;
23485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (iFramesInterval == 0) {
23495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0;
23505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_U32 ret = frameRate * iFramesInterval;
23525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return ret;
23535778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
23545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
235596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatic OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) {
235696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    int32_t tmp;
235796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    if (!msg->findInt32("bitrate-mode", &tmp)) {
235896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        return OMX_Video_ControlRateVariable;
235996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    }
236096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
236196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp);
236296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber}
236396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
23645778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
23655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
23665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
23675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
23685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
23695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
237196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
237296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
23735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
23745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
23755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
23765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
23775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
23785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
23805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
23835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&mpeg4type);
23845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPortIndex = kPortIndexOutput;
23855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
23875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
23885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
23905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
23915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nSliceHeaderSpacing = 0;
23945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bSVH = OMX_FALSE;
23955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bGov = OMX_FALSE;
23965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nAllowedPictureTypes =
23985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
23995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
24015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mpeg4type.nPFrames == 0) {
24025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
24035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nBFrames = 0;
24055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nIDCVLCThreshold = 0;
24065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bACPred = OMX_TRUE;
24075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nMaxPacketSize = 256;
24085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nTimeIncRes = 1000;
24095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nHeaderExtension = 0;
24105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bReversibleVLC = OMX_FALSE;
24115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
24135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
24145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
24155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
24165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
24175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
24185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
24205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
24225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
24235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
24245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
24265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
24275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
24305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
24315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
24335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
24345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
243696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
24375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
24395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
24405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
24435778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
24445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24455778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
24465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
24475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
24485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
24495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
24505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
245296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
245396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
24545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
24555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
24565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
24575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
24585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
24595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
24605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
24615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_H263TYPE h263type;
24645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h263type);
24655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPortIndex = kPortIndexOutput;
24665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
24685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
24695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
24715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
24725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nAllowedPictureTypes =
24755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
24765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
24785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h263type.nPFrames == 0) {
24795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
24805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nBFrames = 0;
24825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
24845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
24855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
24865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
24875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
24885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
24895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
24915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
24935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
24945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
24955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
24975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
24985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bPLUSPTYPEAllowed = OMX_FALSE;
25015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bForceRoundingTypeToZero = OMX_FALSE;
25025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPictureHeaderRepetition = 0;
25035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nGOBHeaderInterval = 0;
25045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
25065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
25075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
25095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
25105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
251296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
25135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
25155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
25165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
25195778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
25205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2521a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar// static
2522a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnarint /* OMX_VIDEO_AVCLEVELTYPE */ ACodec::getAVCLevelFor(
2523a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        int width, int height, int rate, int bitrate,
2524a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        OMX_VIDEO_AVCPROFILETYPE profile) {
2525a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    // convert bitrate to main/baseline profile kbps equivalent
2526a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    switch (profile) {
2527a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        case OMX_VIDEO_AVCProfileHigh10:
2528a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 3000); break;
2529a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        case OMX_VIDEO_AVCProfileHigh:
2530a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 1250); break;
2531a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        default:
2532a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 1000); break;
2533a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    }
2534a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
2535a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    // convert size and rate to MBs
2536a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    width = divUp(width, 16);
2537a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    height = divUp(height, 16);
2538a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    int mbs = width * height;
2539a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    rate *= mbs;
2540a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    int maxDimension = max(width, height);
2541a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
2542a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    static const int limits[][5] = {
2543a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        /*   MBps     MB   dim  bitrate        level */
2544a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    1485,    99,  28,     64, OMX_VIDEO_AVCLevel1  },
2545a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    1485,    99,  28,    128, OMX_VIDEO_AVCLevel1b },
2546a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    3000,   396,  56,    192, OMX_VIDEO_AVCLevel11 },
2547a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    6000,   396,  56,    384, OMX_VIDEO_AVCLevel12 },
2548a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   11880,   396,  56,    768, OMX_VIDEO_AVCLevel13 },
2549a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   11880,   396,  56,   2000, OMX_VIDEO_AVCLevel2  },
2550a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   19800,   792,  79,   4000, OMX_VIDEO_AVCLevel21 },
2551a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   20250,  1620, 113,   4000, OMX_VIDEO_AVCLevel22 },
2552a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   40500,  1620, 113,  10000, OMX_VIDEO_AVCLevel3  },
2553a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  108000,  3600, 169,  14000, OMX_VIDEO_AVCLevel31 },
2554a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  216000,  5120, 202,  20000, OMX_VIDEO_AVCLevel32 },
2555a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  245760,  8192, 256,  20000, OMX_VIDEO_AVCLevel4  },
2556a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  245760,  8192, 256,  50000, OMX_VIDEO_AVCLevel41 },
2557a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  522240,  8704, 263,  50000, OMX_VIDEO_AVCLevel42 },
2558a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  589824, 22080, 420, 135000, OMX_VIDEO_AVCLevel5  },
2559a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  983040, 36864, 543, 240000, OMX_VIDEO_AVCLevel51 },
2560a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        { 2073600, 36864, 543, 240000, OMX_VIDEO_AVCLevel52 },
2561a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    };
2562a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
2563a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    for (size_t i = 0; i < ARRAY_SIZE(limits); i++) {
2564a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        const int (&limit)[5] = limits[i];
2565a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        if (rate <= limit[0] && mbs <= limit[1] && maxDimension <= limit[2]
2566a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar                && bitrate <= limit[3]) {
2567a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            return limit[4];
2568a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        }
2569a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    }
2570a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    return 0;
2571a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar}
2572a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
25735778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
25745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
25755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
25765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
25775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
25785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
258096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
258196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
25825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
25835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
25845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
25855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
25865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
25875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
25885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
25895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25910dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = OK;
25920dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    int32_t intraRefreshMode = 0;
25930dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) {
25940dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode);
25950dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (err != OK) {
25960dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
25970dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong                    err, intraRefreshMode);
25980dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return err;
25990dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
26000dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
26010dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
26025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_AVCTYPE h264type;
26035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h264type);
26045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nPortIndex = kPortIndexOutput;
26055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26060dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    err = mOMX->getParameter(
26075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
26085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
26105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
26115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nAllowedPictureTypes =
26145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
26155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
26175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
26185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
26195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
26205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
26215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
26225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
26245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
26265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
26275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
26285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
26305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
26315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // XXX
26347c25df82dfc8bbedb58608242f0d923a4594bb14James Dong    if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) {
26357c25df82dfc8bbedb58608242f0d923a4594bb14James Dong        ALOGW("Use baseline profile instead of %d for AVC recording",
26367c25df82dfc8bbedb58608242f0d923a4594bb14James Dong            h264type.eProfile);
26375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
26385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
26415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nSliceHeaderSpacing = 0;
26425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bUseHadamard = OMX_TRUE;
26435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefFrames = 1;
26445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nBFrames = 0;
26455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
26465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (h264type.nPFrames == 0) {
26475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
26485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
26495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx10ActiveMinus1 = 0;
26505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx11ActiveMinus1 = 0;
26515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bEntropyCodingCABAC = OMX_FALSE;
26525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bWeightedPPrediction = OMX_FALSE;
26535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bconstIpred = OMX_FALSE;
26545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirect8x8Inference = OMX_FALSE;
26555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirectSpatialTemporal = OMX_FALSE;
26565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nCabacInitIdc = 0;
26575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.nBFrames != 0) {
26605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
26615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableUEP = OMX_FALSE;
26645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableFMO = OMX_FALSE;
26655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableASO = OMX_FALSE;
26665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableRS = OMX_FALSE;
26675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bFrameMBsOnly = OMX_TRUE;
26685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bMBAFF = OMX_FALSE;
26695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
26705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
26725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
26735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
26755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
26765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
267896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return configureBitrate(bitrate, bitrateMode);
26795778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
26805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2681c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachadstatus_t ACodec::setupHEVCEncoderParameters(const sp<AMessage> &msg) {
2682c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    int32_t bitrate, iFrameInterval;
2683c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findInt32("bitrate", &bitrate)
2684c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
2685c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return INVALID_OPERATION;
2686c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2687c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2688c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
2689c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2690c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    float frameRate;
2691c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findFloat("frame-rate", &frameRate)) {
2692c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t tmp;
2693c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("frame-rate", &tmp)) {
2694c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
2695c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
2696c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        frameRate = (float)tmp;
2697c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2698c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2699c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_PARAM_HEVCTYPE hevcType;
2700c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    InitOMXParams(&hevcType);
2701c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    hevcType.nPortIndex = kPortIndexOutput;
2702c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2703c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    status_t err = OK;
2704c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    err = mOMX->getParameter(
2705c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
2706c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
2707c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
2708c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2709c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2710c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    int32_t profile;
2711c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (msg->findInt32("profile", &profile)) {
2712c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t level;
2713c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("level", &level)) {
2714c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
2715c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
2716c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2717c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        err = verifySupportForProfileAndLevel(profile, level);
2718c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (err != OK) {
2719c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return err;
2720c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
2721c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2722c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eProfile = static_cast<OMX_VIDEO_HEVCPROFILETYPE>(profile);
2723c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eLevel = static_cast<OMX_VIDEO_HEVCLEVELTYPE>(level);
2724c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2725c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2726c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    // TODO: Need OMX structure definition for setting iFrameInterval
2727c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2728c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    err = mOMX->setParameter(
2729c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
2730c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
2731c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
2732c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2733c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2734c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    return configureBitrate(bitrate, bitrateMode);
2735c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad}
2736c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
273789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huberstatus_t ACodec::setupVPXEncoderParameters(const sp<AMessage> &msg) {
273889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    int32_t bitrate;
27394154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    int32_t iFrameInterval = 0;
27404154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    size_t tsLayers = 0;
27414154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE pattern =
27424154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        OMX_VIDEO_VPXTemporalLayerPatternNone;
27434154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    static const uint32_t kVp8LayerRateAlloction
27444154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS]
27454154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS] = {
27464154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        {100, 100, 100},  // 1 layer
27474154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 60, 100, 100},  // 2 layers {60%, 40%}
27484154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 40,  60, 100},  // 3 layers {40%, 20%, 40%}
27494154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    };
275089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    if (!msg->findInt32("bitrate", &bitrate)) {
275189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        return INVALID_OPERATION;
275289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    }
27534154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    msg->findInt32("i-frame-interval", &iFrameInterval);
275489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
275589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
275689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
27574154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    float frameRate;
27584154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (!msg->findFloat("frame-rate", &frameRate)) {
27594154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        int32_t tmp;
27604154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (!msg->findInt32("frame-rate", &tmp)) {
27614154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            return INVALID_OPERATION;
27624154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
27634154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        frameRate = (float)tmp;
27644154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
27654154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
27664154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    AString tsSchema;
27674154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (msg->findString("ts-schema", &tsSchema)) {
27684154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (tsSchema == "webrtc.vp8.1-layer") {
27694154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
27704154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 1;
27714154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else if (tsSchema == "webrtc.vp8.2-layer") {
27724154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
27734154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 2;
27744154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else if (tsSchema == "webrtc.vp8.3-layer") {
27754154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
27764154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 3;
27774154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else {
27784154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            ALOGW("Unsupported ts-schema [%s]", tsSchema.c_str());
27794154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
27804154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
27814154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
27824154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
27834154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    InitOMXParams(&vp8type);
27844154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    vp8type.nPortIndex = kPortIndexOutput;
27854154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    status_t err = mOMX->getParameter(
27864154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
27874154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            &vp8type, sizeof(vp8type));
27884154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
27894154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (err == OK) {
27904154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (iFrameInterval > 0) {
27914154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nKeyFrameInterval = setPFramesSpacing(iFrameInterval, frameRate);
27924154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
27934154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.eTemporalPattern = pattern;
27944154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.nTemporalLayerCount = tsLayers;
27954154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (tsLayers > 0) {
27964154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            for (size_t i = 0; i < OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS; i++) {
27974154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                vp8type.nTemporalLayerBitrateRatio[i] =
27984154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                    kVp8LayerRateAlloction[tsLayers - 1][i];
27994154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            }
28004154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
28014154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (bitrateMode == OMX_Video_ControlRateConstant) {
28024154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMinQuantizer = 2;
28034154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMaxQuantizer = 63;
28044154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
28054154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
28064154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        err = mOMX->setParameter(
28074154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
28084154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                &vp8type, sizeof(vp8type));
28094154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (err != OK) {
28104154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            ALOGW("Extended VP8 parameters set failed: %d", err);
28114154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
28124154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
28134154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
281489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    return configureBitrate(bitrate, bitrateMode);
281589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber}
281689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
28175778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::verifySupportForProfileAndLevel(
28185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t profile, int32_t level) {
28195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
28205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&params);
28215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    params.nPortIndex = kPortIndexOutput;
28225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (params.nProfileIndex = 0;; ++params.nProfileIndex) {
28245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
28255778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode,
28265778822d86b0337407514b9372562b86edfa91cdAndreas Huber                OMX_IndexParamVideoProfileLevelQuerySupported,
28275778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &params,
28285778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sizeof(params));
28295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
28315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
28325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
28335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
28355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
28365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (profile == supportedProfile && level <= supportedLevel) {
28385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OK;
28395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
28405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28415778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
28425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
284396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatus_t ACodec::configureBitrate(
284496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) {
28455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
28465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&bitrateType);
28475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
28485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
28505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
28515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
28525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
28545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
28555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
285796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    bitrateType.eControlRate = bitrateMode;
28585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nTargetBitrate = bitrate;
28595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
28615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
28625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
28635778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
28645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28655778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupErrorCorrectionParameters() {
28665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
28675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&errorCorrectionType);
28685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nPortIndex = kPortIndexOutput;
28695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
28715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
28725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
28735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
28755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OK;  // Optional feature. Ignore this failure
28765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableHEC = OMX_FALSE;
28795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableResync = OMX_TRUE;
28805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nResynchMarkerSpacing = 256;
28815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
28825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableRVLC = OMX_FALSE;
28835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
28855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
28865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
28875778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
28885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2889f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoFormatOnPort(
2890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
2891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat) {
2892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
2893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
2894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
2895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
2897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
2899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
2902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
2904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // XXX Need a (much) better heuristic to compute input buffer sizes.
2905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const size_t X = 64 * 1024;
2906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (def.nBufferSize < X) {
2907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.nBufferSize = X;
2908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
2912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameWidth = width;
2914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameHeight = height;
2915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
2917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eCompressionFormat = compressionFormat;
2918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eColorFormat = OMX_COLOR_FormatUnused;
2919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
2922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
2925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2927f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::initNativeWindow() {
2928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL) {
2929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
2930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
2933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2936d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Hubersize_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
2937d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    size_t n = 0;
2938d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2939d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2940d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        const BufferInfo &info = mBuffers[portIndex].itemAt(i);
2941d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2942d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
2943d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            ++n;
2944d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        }
2945d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    }
2946d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2947d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    return n;
2948d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber}
2949d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
29507e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubersize_t ACodec::countBuffersOwnedByNativeWindow() const {
29517e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    size_t n = 0;
29527e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
29537e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
29547e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
29557e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
29567e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
29577e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            ++n;
29587e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        }
29597e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
29607e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
29617e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    return n;
29627e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
29637e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
29647e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubervoid ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
29657e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (mNativeWindow == NULL) {
29667e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        return;
29677e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
29687e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
2969e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    while (countBuffersOwnedByNativeWindow() > mNumUndequeuedBuffers
29707e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            && dequeueBufferFromNativeWindow() != NULL) {
2971c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        // these buffers will be submitted as regular buffers; account for this
2972c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        if (mStoreMetaDataInOutputBuffers && mMetaDataBuffersToSubmit > 0) {
2973c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar            --mMetaDataBuffersToSubmit;
2974c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        }
29757e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
29767e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
29777e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
2978f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs(
2979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
2980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
2982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus != BufferInfo::OWNED_BY_US
2984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
2985609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGV("[%s] Buffer %u on port %u still has status %d",
2986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mComponentName.c_str(),
2987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info->mBufferID, portIndex, info->mStatus);
2988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
2989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2995f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs() {
2996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return allYourBuffersAreBelongToUs(kPortIndexInput)
2997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        && allYourBuffersAreBelongToUs(kPortIndexOutput);
2998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3000f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::deferMessage(const sp<AMessage> &msg) {
3001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool wasEmptyBefore = mDeferredQueue.empty();
3002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.push_back(msg);
3003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3005f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::processDeferredMessages() {
3006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> > queue = mDeferredQueue;
3007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.clear();
3008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> >::iterator it = queue.begin();
3010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while (it != queue.end()) {
3011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        onMessageReceived(*it++);
3012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
301503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar// static
3016229d242665c612fd97431d1e7ac004823b47f181Lajos Molnarbool ACodec::describeDefaultColorFormat(DescribeColorFormatParams &params) {
301703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    MediaImage &image = params.sMediaImage;
301803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    memset(&image, 0, sizeof(image));
301903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
302003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mType = MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
302103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mNumPlanes = 0;
302203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
302303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    const OMX_COLOR_FORMATTYPE fmt = params.eColorFormat;
302403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mWidth = params.nFrameWidth;
302503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mHeight = params.nFrameHeight;
302603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
302703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    // only supporting YUV420
302803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    if (fmt != OMX_COLOR_FormatYUV420Planar &&
302903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        fmt != OMX_COLOR_FormatYUV420PackedPlanar &&
303003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        fmt != OMX_COLOR_FormatYUV420SemiPlanar &&
303103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        fmt != OMX_COLOR_FormatYUV420PackedSemiPlanar) {
303203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        ALOGW("do not know color format 0x%x = %d", fmt, fmt);
3033229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return false;
303403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    }
303503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
3036b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    // TEMPORARY FIX for some vendors that advertise sliceHeight as 0
3037b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    if (params.nStride != 0 && params.nSliceHeight == 0) {
3038b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        ALOGW("using sliceHeight=%u instead of what codec advertised (=0)",
3039b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar                params.nFrameHeight);
3040b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        params.nSliceHeight = params.nFrameHeight;
3041b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    }
3042b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar
3043b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    // we need stride and slice-height to be non-zero
3044b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    if (params.nStride == 0 || params.nSliceHeight == 0) {
3045b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        ALOGW("cannot describe color format 0x%x = %d with stride=%u and sliceHeight=%u",
3046b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar                fmt, fmt, params.nStride, params.nSliceHeight);
3047b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        return false;
3048b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    }
3049b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar
305003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    // set-up YUV format
305103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mType = MediaImage::MEDIA_IMAGE_TYPE_YUV;
305203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mNumPlanes = 3;
305303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mBitDepth = 8;
305403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mOffset = 0;
305503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mColInc = 1;
305603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mRowInc = params.nStride;
305703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mHorizSubsampling = 1;
305803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mVertSubsampling = 1;
305903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
306003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    switch (fmt) {
306103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420Planar: // used for YV12
306203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420PackedPlanar:
306303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight;
306403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mColInc = 1;
306503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mRowInc = params.nStride / 2;
306603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mHorizSubsampling = 2;
306703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mVertSubsampling = 2;
306803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
306903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset
307003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    + (params.nStride * params.nSliceHeight / 4);
307103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mColInc = 1;
307203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mRowInc = params.nStride / 2;
307303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mHorizSubsampling = 2;
307403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mVertSubsampling = 2;
307503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            break;
307603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
307703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420SemiPlanar:
307803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            // FIXME: NV21 for sw-encoder, NV12 for decoder and hw-encoder
307903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420PackedSemiPlanar:
308003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            // NV12
308103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight;
308203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mColInc = 2;
308303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mRowInc = params.nStride;
308403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mHorizSubsampling = 2;
308503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mVertSubsampling = 2;
308603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
308703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset + 1;
308803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mColInc = 2;
308903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mRowInc = params.nStride;
309003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mHorizSubsampling = 2;
309103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mVertSubsampling = 2;
309203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            break;
309303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
309403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        default:
309503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            TRESPASS();
309603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    }
3097229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    return true;
3098229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar}
3099229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3100229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar// static
3101229d242665c612fd97431d1e7ac004823b47f181Lajos Molnarbool ACodec::describeColorFormat(
3102229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        const sp<IOMX> &omx, IOMX::node_id node,
3103229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        DescribeColorFormatParams &describeParams)
3104229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar{
3105229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    OMX_INDEXTYPE describeColorFormatIndex;
3106229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    if (omx->getExtensionIndex(
3107229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            node, "OMX.google.android.index.describeColorFormat",
3108229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            &describeColorFormatIndex) != OK ||
3109229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        omx->getParameter(
3110229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            node, describeColorFormatIndex,
3111229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            &describeParams, sizeof(describeParams)) != OK) {
3112229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return describeDefaultColorFormat(describeParams);
3113229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    }
3114229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    return describeParams.sMediaImage.mType !=
3115229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
3116229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar}
3117229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3118229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar// static
3119229d242665c612fd97431d1e7ac004823b47f181Lajos Molnarbool ACodec::isFlexibleColorFormat(
3120229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar         const sp<IOMX> &omx, IOMX::node_id node,
3121229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar         uint32_t colorFormat, OMX_U32 *flexibleEquivalent) {
3122229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    DescribeColorFormatParams describeParams;
3123229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    InitOMXParams(&describeParams);
3124229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.eColorFormat = (OMX_COLOR_FORMATTYPE)colorFormat;
3125229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    // reasonable dummy values
3126229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nFrameWidth = 128;
3127229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nFrameHeight = 128;
3128229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nStride = 128;
3129229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nSliceHeight = 128;
3130229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3131229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    CHECK(flexibleEquivalent != NULL);
3132229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3133229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    if (!describeColorFormat(omx, node, describeParams)) {
3134229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return false;
3135229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    }
3136229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3137229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    const MediaImage &img = describeParams.sMediaImage;
3138229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    if (img.mType == MediaImage::MEDIA_IMAGE_TYPE_YUV) {
3139229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        if (img.mNumPlanes != 3 ||
3140229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            img.mPlane[img.Y].mHorizSubsampling != 1 ||
3141229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            img.mPlane[img.Y].mVertSubsampling != 1) {
3142229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            return false;
3143229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
3144229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3145229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        // YUV 420
3146229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        if (img.mPlane[img.U].mHorizSubsampling == 2
3147229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.U].mVertSubsampling == 2
3148229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.V].mHorizSubsampling == 2
3149229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.V].mVertSubsampling == 2) {
3150229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            // possible flexible YUV420 format
3151229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            if (img.mBitDepth <= 8) {
3152229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar               *flexibleEquivalent = OMX_COLOR_FormatYUV420Flexible;
3153229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar               return true;
3154229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            }
3155229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
3156229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    }
3157229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    return false;
315803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar}
315903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
3160e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarstatus_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> &notify) {
3161e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    // TODO: catch errors an return them instead of using CHECK
316231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
316331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    InitOMXParams(&def);
3164e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    def.nPortIndex = portIndex;
316531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
316631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ(mOMX->getParameter(
316731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)),
316831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber             (status_t)OK);
316931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3170e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ((int)def.eDir,
3171e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            (int)(portIndex == kPortIndexOutput ? OMX_DirOutput : OMX_DirInput));
317231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
317331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    switch (def.eDomain) {
317431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainVideo:
317531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
317631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
3177e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            switch ((int)videoDef->eCompressionFormat) {
3178e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_VIDEO_CodingUnused:
3179e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3180e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(mIsEncoder ^ (portIndex == kPortIndexOutput));
3181e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
3182e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3183e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("stride", videoDef->nStride);
3184e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("slice-height", videoDef->nSliceHeight);
3185e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("color-format", videoDef->eColorFormat);
3186e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
318703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    DescribeColorFormatParams describeParams;
318803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    InitOMXParams(&describeParams);
318903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    describeParams.eColorFormat = videoDef->eColorFormat;
319003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    describeParams.nFrameWidth = videoDef->nFrameWidth;
319103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    describeParams.nFrameHeight = videoDef->nFrameHeight;
319203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    describeParams.nStride = videoDef->nStride;
319303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    describeParams.nSliceHeight = videoDef->nSliceHeight;
319403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
3195229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                    if (describeColorFormat(mOMX, mNode, describeParams)) {
319603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                        notify->setBuffer(
319703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                                "image-data",
319803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                                ABuffer::CreateAsCopy(
319903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                                        &describeParams.sMediaImage,
320003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                                        sizeof(describeParams.sMediaImage)));
320103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    }
320203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
320391a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                    if (portIndex != kPortIndexOutput) {
320491a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                        // TODO: also get input crop
320591a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                        break;
320691a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                    }
320791a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar
3208e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_CONFIG_RECTTYPE rect;
3209e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&rect);
321091a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                    rect.nPortIndex = portIndex;
3211e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3212e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    if (mOMX->getConfig(
321391a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                mNode,
321491a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                (portIndex == kPortIndexOutput ?
321591a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                        OMX_IndexConfigCommonOutputCrop :
321691a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                        OMX_IndexConfigCommonInputCrop),
3217e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &rect, sizeof(rect)) != OK) {
3218e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nLeft = 0;
3219e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nTop = 0;
3220e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nWidth = videoDef->nFrameWidth;
3221e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nHeight = videoDef->nFrameHeight;
3222e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    }
322331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3224e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nLeft, 0);
3225e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nTop, 0);
3226e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nWidth, 0u);
3227e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nHeight, 0u);
3228e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_LE(rect.nLeft + rect.nWidth - 1, videoDef->nFrameWidth);
3229e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_LE(rect.nTop + rect.nHeight - 1, videoDef->nFrameHeight);
3230e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3231e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setRect(
3232577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            "crop",
3233577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nLeft,
3234577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nTop,
3235e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                            rect.nLeft + rect.nWidth - 1,
3236e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                            rect.nTop + rect.nHeight - 1);
3237e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3238e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3239e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
32404730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
32414730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP8:
32424730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP9:
32434730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                {
32444730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
32454730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    InitOMXParams(&vp8type);
32464730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    vp8type.nPortIndex = kPortIndexOutput;
32474730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    status_t err = mOMX->getParameter(
32484730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            mNode,
32494730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
32504730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            &vp8type,
32514730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            sizeof(vp8type));
32524730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
32534730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    if (err == OK) {
32544730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        AString tsSchema = "none";
32554730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        if (vp8type.eTemporalPattern
32564730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                == OMX_VIDEO_VPXTemporalLayerPatternWebRTC) {
32574730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            switch (vp8type.nTemporalLayerCount) {
32584730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 1:
32594730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
32604730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.1-layer";
32614730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
32624730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
32634730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 2:
32644730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
32654730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.2-layer";
32664730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
32674730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
32684730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 3:
32694730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
32704730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.3-layer";
32714730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
32724730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
32734730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                default:
32744730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
32754730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
32764730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
32774730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            }
32784730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        }
32794730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        notify->setString("ts-schema", tsSchema);
32804730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    }
32814730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    // Fall through to set up mime.
32824730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                }
32834730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
3284e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                default:
3285e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3286e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(mIsEncoder ^ (portIndex == kPortIndexInput));
3287e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    AString mime;
3288e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    if (GetMimeTypeForVideoCoding(
3289e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        videoDef->eCompressionFormat, &mime) != OK) {
3290e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", "application/octet-stream");
3291e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    } else {
3292e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", mime.c_str());
3293e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    }
3294e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3295e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
329631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            }
3297e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3298e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("width", videoDef->nFrameWidth);
3299e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("height", videoDef->nFrameHeight);
330031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
330131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
330231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
330331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainAudio:
330431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
330531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
330631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
330797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            switch ((int)audioDef->eEncoding) {
3308e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingPCM:
3309e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3310e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_PCMMODETYPE params;
3311e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3312e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3313e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3314e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3315e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioPcm,
3316e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3317e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3318e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
331914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_GT(params.nChannels, 0);
3320e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK(params.nChannels == 1 || params.bInterleaved);
3321e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(params.nBitPerSample, 16u);
332214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
332314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.eNumData,
332414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_NumericalDataSigned);
332514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
332614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.ePCMMode,
332714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_AUDIO_PCMModeLinear);
3328e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3329e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
3330e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
3331e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSamplingRate);
3332e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3333e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mChannelMaskPresent) {
3334e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("channel-mask", mChannelMask);
33358b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                    }
3336e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
33378b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                }
33389806555d3930be43e11106281dee354820ac1c88Andreas Huber
3339e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAAC:
3340e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3341e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AACPROFILETYPE params;
3342e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3343e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3344e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3345e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3346e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAac,
3347e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3348e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3349e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3350e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
3351e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
3352e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
3353e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
3354e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
3355e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3356e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAMR:
3357e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3358e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AMRTYPE params;
3359e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3360e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
33619806555d3930be43e11106281dee354820ac1c88Andreas Huber
3362e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3363e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAmr,
3364e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3365e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3366e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3367e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", 1);
3368e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) {
3369e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
3370e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_WB);
3371e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3372e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 16000);
3373e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    } else {
3374e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
3375e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
3376e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3377e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 8000);
3378e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
3379e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
3380e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
3381e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3382e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingFLAC:
3383e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3384e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_FLACTYPE params;
3385e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3386e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3387e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3388e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3389e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioFlac,
3390e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3391e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3392e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3393e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC);
3394e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
3395e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
3396e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
3397e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
3398e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3399e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingMP3:
3400e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3401e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_MP3TYPE params;
3402e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
3403e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3404e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3405e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_EQ(mOMX->getParameter(
3406e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                mNode, OMX_IndexParamAudioMp3,
3407e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &params, sizeof(params)),
3408e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                             (status_t)OK);
3409e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3410e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MPEG);
3411e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
3412e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
3413e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3414e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
3415e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3416e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingVORBIS:
3417e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3418e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_VORBISTYPE params;
3419e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
3420e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3421e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3422e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_EQ(mOMX->getParameter(
3423e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                mNode, OMX_IndexParamAudioVorbis,
3424e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &params, sizeof(params)),
3425e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                             (status_t)OK);
3426e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3427e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_VORBIS);
3428e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
3429e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
3430e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3431e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
3432e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
343397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                case OMX_AUDIO_CodingAndroidAC3:
343497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                {
343597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    OMX_AUDIO_PARAM_ANDROID_AC3TYPE params;
343697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    InitOMXParams(&params);
3437e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
343897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
343997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    CHECK_EQ((status_t)OK, mOMX->getParameter(
344097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            mNode,
344197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
344297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            &params,
344397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            sizeof(params)));
344497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
344597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AC3);
344697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("channel-count", params.nChannels);
344797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("sample-rate", params.nSampleRate);
344897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    break;
344997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                }
3450e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
34518c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                case OMX_AUDIO_CodingAndroidOPUS:
34528c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                {
34538c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    OMX_AUDIO_PARAM_ANDROID_OPUSTYPE params;
34548c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    InitOMXParams(&params);
34558c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    params.nPortIndex = portIndex;
34568c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
34578c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    CHECK_EQ((status_t)OK, mOMX->getParameter(
34588c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            mNode,
34598c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus,
34608c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            &params,
34618c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            sizeof(params)));
34628c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
34638c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_OPUS);
34648c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("channel-count", params.nChannels);
34658c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("sample-rate", params.nSampleRate);
34668c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    break;
34678c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                }
34688c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
346910d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                case OMX_AUDIO_CodingG711:
347010d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                {
347110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    OMX_AUDIO_PARAM_PCMMODETYPE params;
347210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    InitOMXParams(&params);
347310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    params.nPortIndex = portIndex;
347410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
347510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    CHECK_EQ((status_t)OK, mOMX->getParameter(
347610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                            mNode,
347710d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                            (OMX_INDEXTYPE)OMX_IndexParamAudioPcm,
347810d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                            &params,
347910d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                            sizeof(params)));
348010d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
348110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    const char *mime = NULL;
348210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    if (params.ePCMMode == OMX_AUDIO_PCMModeMULaw) {
348310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_G711_MLAW;
348410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    } else if (params.ePCMMode == OMX_AUDIO_PCMModeALaw) {
348510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_G711_ALAW;
348610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    } else { // params.ePCMMode == OMX_AUDIO_PCMModeLinear
348710d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_RAW;
348810d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    }
348910d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setString("mime", mime);
349010d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setInt32("channel-count", params.nChannels);
349110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setInt32("sample-rate", params.nSamplingRate);
349210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    break;
349310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                }
349410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
3495e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                default:
3496e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    ALOGE("UNKNOWN AUDIO CODING: %d\n", audioDef->eEncoding);
3497e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    TRESPASS();
3498e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
349931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
350031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
350131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
350231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        default:
350331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            TRESPASS();
350431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    }
350531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3506e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    return OK;
3507e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar}
3508e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3509e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarvoid ACodec::sendFormatChange(const sp<AMessage> &reply) {
3510e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    sp<AMessage> notify = mNotify->dup();
3511e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    notify->setInt32("what", kWhatOutputFormatChanged);
3512e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3513e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ(getPortFormat(kPortIndexOutput, notify), (status_t)OK);
3514e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3515e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    AString mime;
3516e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK(notify->findString("mime", &mime));
3517e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3518e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    int32_t left, top, right, bottom;
3519e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if (mime == MEDIA_MIMETYPE_VIDEO_RAW &&
3520e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        mNativeWindow != NULL &&
3521e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->findRect("crop", &left, &top, &right, &bottom)) {
3522e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        // notify renderer of the crop change
3523e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        // NOTE: native window uses extended right-bottom coordinate
3524e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        reply->setRect("crop", left, top, right + 1, bottom + 1);
3525e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    } else if (mime == MEDIA_MIMETYPE_AUDIO_RAW &&
3526e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar               (mEncoderDelay || mEncoderPadding)) {
3527e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        int32_t channelCount;
3528e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        CHECK(notify->findInt32("channel-count", &channelCount));
3529e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        size_t frameSize = channelCount * sizeof(int16_t);
3530e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        if (mSkipCutBuffer != NULL) {
3531e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            size_t prevbufsize = mSkipCutBuffer->size();
3532e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            if (prevbufsize != 0) {
3533e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                ALOGW("Replacing SkipCutBuffer holding %d "
3534e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                      "bytes",
3535e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                      prevbufsize);
3536e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            }
3537e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        }
3538e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        mSkipCutBuffer = new SkipCutBuffer(
3539e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                mEncoderDelay * frameSize,
3540e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                mEncoderPadding * frameSize);
3541e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
3542e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
354331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->post();
354431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
354531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mSentFormat = true;
354631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber}
354731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
35485778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
3549cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    sp<AMessage> notify = mNotify->dup();
3550d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatError);
3551251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    ALOGE("signalError(omxError %#x, internalError %d)", error, internalError);
3552251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
3553251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (internalError == UNKNOWN_ERROR) { // find better error code
3554251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        const status_t omxStatus = statusFromOMXError(error);
3555251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        if (omxStatus != 0) {
3556251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            internalError = omxStatus;
3557251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        } else {
3558251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            ALOGW("Invalid OMX error %#x", error);
3559251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        }
3560251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
35615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("err", internalError);
3562251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    notify->setInt32("actionCode", ACTION_CODE_FATAL); // could translate from OMX error.
3563cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->post();
3564cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber}
3565cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber
3566bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huberstatus_t ACodec::pushBlankBuffersToNativeWindow() {
3567bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    status_t err = NO_ERROR;
3568bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    ANativeWindowBuffer* anb = NULL;
3569bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int numBufs = 0;
3570bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int minUndequeuedBufs = 0;
3571bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3572bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We need to reconnect to the ANativeWindow as a CPU client to ensure that
3573bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // no frames get dropped by SurfaceFlinger assuming that these are video
3574bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // frames.
3575bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_disconnect(mNativeWindow.get(),
3576bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_MEDIA);
3577bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3578bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
3579bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3580bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
3581bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3582bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3583bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_connect(mNativeWindow.get(),
3584bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_CPU);
3585bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3586bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
3587bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3588bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
3589bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3590bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3591bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffers_geometry(mNativeWindow.get(), 1, 1,
3592bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            HAL_PIXEL_FORMAT_RGBX_8888);
3593bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3594bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffers_geometry failed: %s (%d)",
3595bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3596bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
3597bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3598bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
359987eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin    err = native_window_set_scaling_mode(mNativeWindow.get(),
360087eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
360187eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin    if (err != NO_ERROR) {
360287eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin        ALOGE("error pushing blank_frames: set_scaling_mode failed: %s (%d)",
360387eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin              strerror(-err), -err);
360487eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin        goto error;
3605bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3606bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3607bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_usage(mNativeWindow.get(),
3608bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            GRALLOC_USAGE_SW_WRITE_OFTEN);
3609bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3610bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_usage failed: %s (%d)",
3611bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3612bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
3613bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3614bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3615bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = mNativeWindow->query(mNativeWindow.get(),
3616bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs);
3617bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3618bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: MIN_UNDEQUEUED_BUFFERS query "
3619bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                "failed: %s (%d)", strerror(-err), -err);
3620bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
3621bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3622bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3623bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    numBufs = minUndequeuedBufs + 1;
3624bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffer_count(mNativeWindow.get(), numBufs);
3625bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3626bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffer_count failed: %s (%d)",
3627bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3628bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
3629bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3630bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3631bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We  push numBufs + 1 buffers to ensure that we've drawn into the same
3632bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // buffer twice.  This should guarantee that the buffer has been displayed
3633bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // on the screen and then been replaced, so an previous video frames are
3634bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // guaranteed NOT to be currently displayed.
3635bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    for (int i = 0; i < numBufs + 1; i++) {
36361e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        int fenceFd = -1;
36371e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &anb);
3638bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3639bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: dequeueBuffer failed: %s (%d)",
3640bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3641bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
3642bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3643bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3644bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
3645bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3646bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Fill the buffer with the a 1x1 checkerboard pattern ;)
3647bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        uint32_t* img = NULL;
3648bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
3649bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3650bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: lock failed: %s (%d)",
3651bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3652bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
3653bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3654bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3655bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        *img = 0;
3656bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3657bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->unlock();
3658bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3659bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: unlock failed: %s (%d)",
3660bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3661bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
3662bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3663bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3664bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->queueBuffer(mNativeWindow.get(),
36651e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                buf->getNativeBuffer(), -1);
3666bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3667bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: queueBuffer failed: %s (%d)",
3668bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3669bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
3670bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3671bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3672bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        anb = NULL;
3673bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3674bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3675bc098410be55f9d96f394b3981a0c482b83859b6Andreas Hubererror:
3676bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3677bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3678bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after an error.
3679bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (anb != NULL) {
36801e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis            mNativeWindow->cancelBuffer(mNativeWindow.get(), anb, -1);
3681bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3682bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3683bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_disconnect(mNativeWindow.get(),
3684bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
3685bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_connect(mNativeWindow.get(),
3686bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
3687bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3688bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
3689bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    } else {
3690bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after success.
3691bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_disconnect(mNativeWindow.get(),
3692bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
3693bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3694bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
3695bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3696bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
3697bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3698bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3699bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_connect(mNativeWindow.get(),
3700bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
3701bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3702bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
3703bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3704bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
3705bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3706bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3707bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return NO_ERROR;
3708bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3709bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber}
3710bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3713eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberACodec::PortDescription::PortDescription() {
3714eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3715eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3716496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t ACodec::requestIDRFrame() {
3717496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    if (!mIsEncoder) {
3718496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        return ERROR_UNSUPPORTED;
3719496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    }
3720496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
3721496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    OMX_CONFIG_INTRAREFRESHVOPTYPE params;
3722496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    InitOMXParams(&params);
3723496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
3724496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.nPortIndex = kPortIndexOutput;
3725496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.IntraRefreshVOP = OMX_TRUE;
3726496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
3727496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    return mOMX->setConfig(
3728496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            mNode,
3729496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            OMX_IndexConfigVideoIntraVOPRefresh,
3730496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            &params,
3731496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            sizeof(params));
3732496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
3733496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
3734eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubervoid ACodec::PortDescription::addBuffer(
3735eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        IOMX::buffer_id id, const sp<ABuffer> &buffer) {
3736eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBufferIDs.push_back(id);
3737eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBuffers.push_back(buffer);
3738eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3739eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3740eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersize_t ACodec::PortDescription::countBuffers() {
3741eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.size();
3742eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3743eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3744eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberIOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const {
3745eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.itemAt(index);
3746eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3747eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3748eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const {
3749eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBuffers.itemAt(index);
3750eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3751eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3752eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber////////////////////////////////////////////////////////////////////////////////
3753eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3754f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
3755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : AState(parentState),
3756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mCodec(codec) {
3757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3759ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas HuberACodec::BaseState::PortMode ACodec::BaseState::getPortMode(
3760ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
3761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return KEEP_BUFFERS;
3762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3764f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
3765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatInputBufferFilled:
3767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onInputBufferFilled(msg);
3769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatOutputBufferDrained:
3773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onOutputBufferDrained(msg);
3775f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatOMXMessage:
3779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXMessage(msg);
3781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
37837cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
37847cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
37857cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
3786251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            // This may result in an app illegal state exception.
37877cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            ALOGE("Message 0x%x was not handled", msg->what());
37887cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
37897cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            return true;
37907cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
37917cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
3792ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        case ACodec::kWhatOMXDied:
3793ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        {
3794251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            // This will result in kFlagSawMediaServerDie handling in MediaCodec.
3795ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            ALOGE("OMX/mediaserver died, signalling error!");
3796ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT);
3797ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            break;
3798ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        }
3799ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
3802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3807f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
3808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t type;
3809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findInt32("type", &type));
3810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
38115e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // there is a possibility that this is an outstanding message for a
38125e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // codec that we have already destroyed
38135e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    if (mCodec->mNode == NULL) {
38145e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar        ALOGI("ignoring message as already freed component: %s",
38155e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar                msg->debugString().c_str());
38165e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar        return true;
38175e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    }
38185e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar
3819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::node_id nodeID;
3820609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("node", (int32_t*)&nodeID));
3821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(nodeID, mCodec->mNode);
3822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (type) {
3824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EVENT:
3825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t event, data1, data2;
3827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("event", &event));
3828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data1", &data1));
3829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data2", &data2));
3830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
38310af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            if (event == OMX_EventCmdComplete
38320af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data1 == OMX_CommandFlush
38330af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data2 == (int32_t)OMX_ALL) {
38340af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // Use of this notification is not consistent across
38350af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // implementations. We'll drop this notification and rely
38360af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // on flush-complete notifications on the individual port
38370af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // indices instead.
38380af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
38390af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                return true;
38400af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            }
38410af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
3842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEvent(
3843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_EVENTTYPE>(event),
3844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data1),
3845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data2));
3846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EMPTY_BUFFER_DONE:
3849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3850f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
3851609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
3852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEmptyBufferDone(bufferID);
3854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::FILL_BUFFER_DONE:
3857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
3859609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
3860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t rangeOffset, rangeLength, flags;
3862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs;
3863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_offset", &rangeOffset));
3865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_length", &rangeLength));
3866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("flags", &flags));
3867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt64("timestamp", &timeUs));
3868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXFillBufferDone(
3870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    bufferID,
3871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (size_t)rangeOffset, (size_t)rangeLength,
3872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (OMX_U32)flags,
3873784e24e386b088c05d653ab482f2e95cb53e3d01Andy Hung                    timeUs);
3874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
3878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3882f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEvent(
3883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (event != OMX_EventError) {
38853856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] EVENT(%d, 0x%08lx, 0x%08lx)",
3886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mCodec->mComponentName.c_str(), event, data1, data2);
3887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return false;
3889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
389129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block    ALOGE("[%s] ERROR(0x%08lx)", mCodec->mComponentName.c_str(), data1);
3892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3893251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // verify OMX component sends back an error we expect.
3894251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    OMX_ERRORTYPE omxError = (OMX_ERRORTYPE)data1;
3895251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (!isOMXError(omxError)) {
3896251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        ALOGW("Invalid OMX error %#x", omxError);
3897251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        omxError = OMX_ErrorUndefined;
3898251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
3899251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    mCodec->signalError(omxError);
3900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3904f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID) {
39053856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] onOMXEmptyBufferDone %p",
3906349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber         mCodec->mComponentName.c_str(), bufferID);
3907349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexInput, bufferID);
3910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
3912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
391496e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // We're in "store-metadata-in-buffers" mode, the underlying
391596e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // OMX component had access to data that's implicitly refcounted
391696e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // by this "MediaBuffer" object. Now that the OMX component has
391796e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // told us that it's done with the input buffer, we can decrement
391896e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // the mediaBuffer's reference count.
391996e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    info->mData->setMediaBufferBase(NULL);
3920d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
3922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            postFillThisBuffer(info);
3929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();  // Not currently used
3935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3942f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
3943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
3944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
3948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
3950d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatFillThisBuffer);
3951609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    notify->setInt32("buffer-id", info->mBufferID);
3952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mData->meta()->clear();
39542d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    notify->setBuffer("buffer", info->mData);
3955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec->id());
3957609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    reply->setInt32("buffer-id", info->mBufferID);
3958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setMessage("reply", reply);
3960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->post();
3962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
3964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3966f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
3967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
3968609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
39692d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    sp<ABuffer> buffer;
3970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t err = OK;
39715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool eos = false;
3972a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar    PortMode mode = getPortMode(kPortIndexInput);
39735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39742d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    if (!msg->findBuffer("buffer", &buffer)) {
3975a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar        /* these are unfilled buffers returned by client */
3976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findInt32("err", &err));
3977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
39787fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        if (err == OK) {
39797fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            /* buffers with no errors are returned on MediaCodec.flush */
39807fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            mode = KEEP_BUFFERS;
39817fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        } else {
39827fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            ALOGV("[%s] saw error %d instead of an input buffer",
39837fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                 mCodec->mComponentName.c_str(), err);
39847fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            eos = true;
39857fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        }
39863831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
39872d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber        buffer.clear();
3988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
39905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
39915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
39925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
39935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = ERROR_END_OF_STREAM;
39945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
39955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
3997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_UPSTREAM);
3998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
4000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
40045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (eos) {
4005dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (!mCodec->mPortEOS[kPortIndexInput]) {
4006dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
4007dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mInputEOSResult = err;
4008dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
4009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
40155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
4016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int64_t timeUs;
4017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
4018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
4020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t isCSD;
4022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
4023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
4024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
4025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
40265778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (eos) {
40275778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    flags |= OMX_BUFFERFLAG_EOS;
40285778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
40295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer != info->mData) {
4031d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGV("[%s] Needs to copy input data for buffer %p. (%p != %p)",
4032d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(),
4033d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         bufferID,
4034d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         buffer.get(), info->mData.get());
4035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    CHECK_LE(buffer->size(), info->mData->capacity());
4037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    memcpy(info->mData->data(), buffer->data(), buffer->size());
4038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
4039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4040078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
40413856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ codec specific data",
4042078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID);
40435778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else if (flags & OMX_BUFFERFLAG_EOS) {
40445778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] calling emptyBuffer %p w/ EOS",
40455778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str(), bufferID);
4046078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                } else {
4047d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
4048d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGI("[%s] calling emptyBuffer %p w/ time %lld us",
4049d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
4050d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#else
40513856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ time %lld us",
4052078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
4053d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
4054078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                }
4055349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4056d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
4057d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ACodec::BufferStats stats;
4058d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
4059d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mFillBufferDoneTimeUs = -1ll;
4060d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mCodec->mBufferStats.add(timeUs, stats);
4061d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
4062d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4063054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                if (mCodec->mStoreMetaDataInOutputBuffers) {
4064054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    // try to submit an output buffer for each input buffer
4065054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    PortMode outputMode = getPortMode(kPortIndexOutput);
4066054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4067054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    ALOGV("MetaDataBuffersToSubmit=%u portMode=%s",
4068054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            mCodec->mMetaDataBuffersToSubmit,
4069054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            (outputMode == FREE_BUFFERS ? "FREE" :
4070054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                             outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
4071054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    if (outputMode == RESUBMIT_BUFFERS) {
4072e53350373ac516257b4f8956ff1e3f1ac48f607eLajos Molnar                        mCodec->submitOutputMetaDataBuffer();
4073054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    }
4074054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                }
4075054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
4077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
4078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
4079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
4080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            buffer->size(),
4081f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            flags,
4082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            timeUs),
4083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4086f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
40875778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (!eos) {
40885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    getMoreInputDataIfPossible();
40895778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
40905778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] Signalled EOS on the input port",
40915778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str());
40925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40935778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
40945778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mInputEOSResult = err;
40955778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
4096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
4097dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (err != ERROR_END_OF_STREAM) {
40983856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port "
4099dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         "due to error %d",
4100dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str(), err);
4101dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                } else {
41023856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port",
4103dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str());
4104dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
4105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
41063856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] calling emptyBuffer %p signalling EOS",
4107349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                     mCodec->mComponentName.c_str(), bufferID);
4108349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
4110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
4111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
4112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
4113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
4114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_BUFFERFLAG_EOS,
4115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0),
4116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexInput] = true;
4121dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                mCodec->mInputEOSResult = err;
4122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4125625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih
4126625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih        default:
4127625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
4128625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih            break;
4129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4132f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::getMoreInputDataIfPossible() {
4133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
4134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
4135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *eligible = NULL;
4138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
4140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
4141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
4143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
4144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // There's already a "read" pending.
4145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
4146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
4148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_US) {
4150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            eligible = info;
4151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (eligible == NULL) {
4155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
4156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(eligible);
4159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4161f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXFillBufferDone(
4162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferID,
4163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        size_t rangeOffset, size_t rangeLength,
4164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 flags,
4165784e24e386b088c05d653ab482f2e95cb53e3d01Andy Hung        int64_t timeUs) {
4166609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] onOMXFillBufferDone %u time %" PRId64 " us, flags = 0x%08x",
41675778822d86b0337407514b9372562b86edfa91cdAndreas Huber         mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
4168349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
4170d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4171d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
4172d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    index = mCodec->mBufferStats.indexOfKey(timeUs);
4173d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (index >= 0) {
4174d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
4175d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
4176d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4177d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ALOGI("frame PTS %lld: %lld",
4178d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                timeUs,
4179d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
4180d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4181d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mCodec->mBufferStats.removeItemsAt(index);
4182d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats = NULL;
4183d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
4184d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
4185d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
4187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
4188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
4190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4191054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mDequeuedAt = ++mCodec->mDequeueCounter;
4192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
4193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
4195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
42025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (rangeLength == 0 && !(flags & OMX_BUFFERFLAG_EOS)) {
4203609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                ALOGV("[%s] calling fillBuffer %u",
42045778822d86b0337407514b9372562b86edfa91cdAndreas Huber                     mCodec->mComponentName.c_str(), info->mBufferID);
4205349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
42065778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK_EQ(mCodec->mOMX->fillBuffer(
42075778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mCodec->mNode, info->mBufferID),
42085778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         (status_t)OK);
4209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
42105778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
42115778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
42125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
421331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4214577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            sp<AMessage> reply =
4215577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                new AMessage(kWhatOutputBufferDrained, mCodec->id());
4216577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
42174bdda35319d5f46efea2089b865c8a64816389cdMarco Nelissen            if (!mCodec->mSentFormat && rangeLength > 0) {
4218577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->sendFormatChange(reply);
42195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
4220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4221308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            if (mCodec->mUseMetadataOnEncoderOutput) {
4222308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                native_handle_t* handle =
4223308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        *(native_handle_t**)(info->mData->data() + 4);
4224308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setPointer("handle", handle);
4225308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeOffset", rangeOffset);
4226308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeLength", rangeLength);
4227308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            } else {
4228308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->setRange(rangeOffset, rangeLength);
4229308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            }
4230496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#if 0
423121ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen            if (mCodec->mNativeWindow == NULL) {
4232496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                if (IsIDR(info->mData)) {
4233496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                    ALOGI("IDR frame");
4234496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                }
42355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
423621ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen#endif
4237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
42388b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            if (mCodec->mSkipCutBuffer != NULL) {
42398b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                mCodec->mSkipCutBuffer->submit(info->mData);
42408b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            }
42415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mData->meta()->setInt64("timeUs", timeUs);
4242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
42435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4244d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatDrainThisBuffer);
4245609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            notify->setInt32("buffer-id", info->mBufferID);
42462d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            notify->setBuffer("buffer", info->mData);
42475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("flags", flags);
4248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4249609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            reply->setInt32("buffer-id", info->mBufferID);
4250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
42515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setMessage("reply", reply);
4252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
42535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->post();
42545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
42555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
4256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (flags & OMX_BUFFERFLAG_EOS) {
42585778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
42595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                sp<AMessage> notify = mCodec->mNotify->dup();
4261d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar                notify->setInt32("what", CodecBase::kWhatEOS);
4262dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                notify->setInt32("err", mCodec->mInputEOSResult);
4263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->post();
4264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexOutput] = true;
4266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
4273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
4275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
4276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4283f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
4284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
4285609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
4286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
4287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
4288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
4289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM);
4290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4291577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    android_native_rect_t crop;
4292577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    if (msg->findRect("crop",
4293577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            &crop.left, &crop.top, &crop.right, &crop.bottom)) {
4294577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar        CHECK_EQ(0, native_window_set_crop(
4295577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->mNativeWindow.get(), &crop));
4296577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    }
4297577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
4298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t render;
4299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mNativeWindow != NULL
43006aade6058521b0dbd35a9a4620f4d04f02f90444Marco Nelissen            && msg->findInt32("render", &render) && render != 0
430179ee2399b67c7a11042c5904dc1309712a76f8cbJianzheng Zhou            && info->mData != NULL && info->mData->size() != 0) {
43026fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        ATRACE_NAME("render");
4303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The client wants this buffer to be rendered.
4304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4305fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        int64_t timestampNs = 0;
4306fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        if (!msg->findInt64("timestampNs", &timestampNs)) {
4307fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // TODO: it seems like we should use the timestamp
4308fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // in the (media)buffer as it potentially came from
4309fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // an input surface, but we did not propagate it prior to
4310fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // API 20.  Perhaps check for target SDK version.
4311fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#if 0
4312fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            if (info->mData->meta()->findInt64("timeUs", &timestampNs)) {
431347aea1f7c58f5302b16822f9e7e1763f2af04ef5Lajos Molnar                ALOGV("using buffer PTS of %" PRId64, timestampNs);
4314fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar                timestampNs *= 1000;
4315fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            }
4316fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#endif
4317fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
4318fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
43195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err;
4320fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        err = native_window_set_buffers_timestamp(mCodec->mNativeWindow.get(), timestampNs);
4321fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        if (err != OK) {
4322fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            ALOGW("failed to set buffer timestamp: %d", err);
4323fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
4324fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
43255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if ((err = mCodec->mNativeWindow->queueBuffer(
4326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNativeWindow.get(),
43271e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                    info->mGraphicBuffer.get(), -1)) == OK) {
4328cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
4329cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        } else {
4330251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
4331cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
4332cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        }
4333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
43346fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        if (mCodec->mNativeWindow != NULL &&
43356fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar            (info->mData == NULL || info->mData->size() != 0)) {
43366fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar            ATRACE_NAME("frame-drop");
43376fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        }
4338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_US;
4339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
4342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
4347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // We cannot resubmit the buffer we just rendered, dequeue
4350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // the spare instead.
4351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info = mCodec->dequeueBufferFromNativeWindow();
4353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (!mCodec->mPortEOS[kPortIndexOutput]) {
4360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // We cannot resubmit the buffer we just rendered, dequeue
4362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // the spare instead.
4363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info = mCodec->dequeueBufferFromNativeWindow();
4365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
4366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4367c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                if (info != NULL) {
4368609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                    ALOGV("[%s] calling fillBuffer %u",
4369c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                         mCodec->mComponentName.c_str(), info->mBufferID);
4370349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4371c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
4372c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                             (status_t)OK);
4373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4374c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4375c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                }
4376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
4383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
4385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
4386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4393f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::UninitializedState::UninitializedState(ACodec *codec)
4394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4397c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::UninitializedState::stateEntered() {
4398c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("Now uninitialized");
4399ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4400ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (mDeathNotifier != NULL) {
4401ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mCodec->mOMX->asBinder()->unlinkToDeath(mDeathNotifier);
4402ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
4403ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
4404ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4405ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNativeWindow.clear();
4406ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNode = NULL;
4407ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mOMX.clear();
4408ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mQuirks = 0;
4409ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mFlags = 0;
4410308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    mCodec->mUseMetadataOnEncoderOutput = 0;
4411ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mComponentName.clear();
4412c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4413c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4414f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
4415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatSetup:
4419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onSetup(msg);
4421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
44265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case ACodec::kWhatAllocateComponent:
44275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
44285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            onAllocateComponent(msg);
44295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            handled = true;
44305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
44315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
44325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatShutdown:
4434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4435c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
4436c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
4437c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
443854b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            ALOGW_IF(keepComponentAllocated,
443954b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar                     "cannot keep component allocated on shutdown in Uninitialized state");
4440c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4442d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
4443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
4444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4446c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
4447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatFlush:
4450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4452d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
4453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
4454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4456c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
4457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
4461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4466f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::UninitializedState::onSetup(
4467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4468c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (onAllocateComponent(msg)
4469c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            && mCodec->mLoadedState->onConfigureComponent(msg)) {
4470c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mLoadedState->onStart();
4471c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
44725778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
44735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4474c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
44755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onAllocateComponent");
44765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4477c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    CHECK(mCodec->mNode == NULL);
44785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMXClient client;
4480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(client.connect(), (status_t)OK);
4481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<IOMX> omx = client.interface();
4483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4484ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec->id());
4485ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4486ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mDeathNotifier = new DeathNotifier(notify);
4487ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (omx->asBinder()->linkToDeath(mDeathNotifier) != OK) {
4488ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // This was a local binder, if it dies so do we, we won't care
4489ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // about any notifications in the afterlife.
4490ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
4491ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
4492ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4493e671207115fac3914134c61b336d5fa0242c68caAndreas Huber    Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs;
44945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    AString mime;
4496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
44975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString componentName;
4498d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint32_t quirks = 0;
44997791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen    int32_t encoder = false;
45005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findString("componentName", &componentName)) {
4501e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        ssize_t index = matchingCodecs.add();
4502e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        OMXCodec::CodecNameAndQuirks *entry = &matchingCodecs.editItemAt(index);
4503e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        entry->mName = String8(componentName.c_str());
4504afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
4505e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        if (!OMXCodec::findCodecQuirks(
4506e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                    componentName.c_str(), &entry->mQuirks)) {
4507e671207115fac3914134c61b336d5fa0242c68caAndreas Huber            entry->mQuirks = 0;
4508afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
45095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
45105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(msg->findString("mime", &mime));
45115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
45125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("encoder", &encoder)) {
45135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder = false;
45145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
45155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
45165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMXCodec::findMatchingCodecs(
45175778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mime.c_str(),
45185778822d86b0337407514b9372562b86edfa91cdAndreas Huber                encoder, // createEncoder
45195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                NULL,  // matchComponentName
45205778822d86b0337407514b9372562b86edfa91cdAndreas Huber                0,     // flags
4521e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                &matchingCodecs);
45225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
45231065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
45241065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    sp<CodecObserver> observer = new CodecObserver;
45251065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    IOMX::node_id node = NULL;
45261065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
45271065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
45281065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            ++matchIndex) {
4529e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        componentName = matchingCodecs.itemAt(matchIndex).mName.string();
4530e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        quirks = matchingCodecs.itemAt(matchIndex).mQuirks;
4531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4532da153975581fb3161a30452348a5b26ee72d9255Elliott Hughes        pid_t tid = gettid();
4533078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        int prevPriority = androidGetThreadPriority(tid);
4534078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
45351065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        status_t err = omx->allocateNode(componentName.c_str(), observer, &node);
4536078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, prevPriority);
4537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
45381065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        if (err == OK) {
45391065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            break;
45407a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He        } else {
45417a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He            ALOGW("Allocating component '%s' failed, try next one.", componentName.c_str());
45421065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
45431065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
45441065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        node = NULL;
45451065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    }
45461065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
4547c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    if (node == NULL) {
45485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!mime.empty()) {
45497791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen            ALOGE("Unable to instantiate a %scoder for type '%s'.",
45507791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen                    encoder ? "en" : "de", mime.c_str());
45515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
45527791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen            ALOGE("Unable to instantiate codec '%s'.", componentName.c_str());
45535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
4554c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
4555cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        mCodec->signalError(OMX_ErrorComponentNotFound);
4556c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
4557c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
4558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4559ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    notify = new AMessage(kWhatOMXMessage, mCodec->id());
4560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    observer->setNotificationMessage(notify);
4561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mComponentName = componentName;
4563ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    mCodec->mFlags = 0;
4564ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
4565ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (componentName.endsWith(".secure")) {
4566ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        mCodec->mFlags |= kFlagIsSecure;
45670167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
4568ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
4569ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
4570afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mCodec->mQuirks = quirks;
4571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mOMX = omx;
4572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mNode = node;
4573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
45745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
45755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
4576d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatComponentAllocated);
45775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setString("componentName", mCodec->mComponentName.c_str());
45785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
45795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4580c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4581c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mCodec->changeState(mCodec->mLoadedState);
4582c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4583c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
45845778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
45855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4586c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
4587c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4588c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas HuberACodec::LoadedState::LoadedState(ACodec *codec)
4589c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    : BaseState(codec) {
4590c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4591c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4592c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::stateEntered() {
4593c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
4594c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4595f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mPortEOS[kPortIndexInput] =
4596f6f38287b97ec69b169387add6458f859b770e65Andreas Huber        mCodec->mPortEOS[kPortIndexOutput] = false;
4597f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
4598f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mInputEOSResult = OK;
4599f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
4600054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mDequeueCounter = 0;
4601054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mMetaDataBuffersToSubmit = 0;
4602a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    mCodec->mRepeatFrameDelayUs = -1ll;
4603e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mInputFormat.clear();
4604e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mOutputFormat.clear();
4605054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4606c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (mCodec->mShutdownInProgress) {
4607c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
4608c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4609c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mShutdownInProgress = false;
4610c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mKeepComponentAllocated = false;
4611c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4612c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        onShutdown(keepComponentAllocated);
4613c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
461454b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    mCodec->mExplicitShutdown = false;
4615f393c33e65ae51a7cf168b4e15771b152f996b32Wei Jia
4616f393c33e65ae51a7cf168b4e15771b152f996b32Wei Jia    mCodec->processDeferredMessages();
4617c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4618c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4619c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
4620c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (!keepComponentAllocated) {
4621c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK);
4622c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4623c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->changeState(mCodec->mUninitializedState);
4624c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
4625c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
462654b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    if (mCodec->mExplicitShutdown) {
462754b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        sp<AMessage> notify = mCodec->mNotify->dup();
4628d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
462954b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        notify->post();
463054b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        mCodec->mExplicitShutdown = false;
463154b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    }
4632c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4633c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4634c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
4635c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool handled = false;
4636c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4637c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    switch (msg->what()) {
4638c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatConfigureComponent:
4639c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
4640c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onConfigureComponent(msg);
4641c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
4642c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
4643c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
4644c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
46457cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
46467cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
46477cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            onCreateInputSurface(msg);
46487cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
46497cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
46507cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
46517cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4652c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatStart:
4653c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
4654c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onStart();
4655c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
4656c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
4657c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
4658c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4659c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatShutdown:
4660c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
4661c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
4662c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
4663c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
4664c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
466554b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
4666c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onShutdown(keepComponentAllocated);
4667c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4668c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
4669c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
4670c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
4671c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4672c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatFlush:
4673c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
4674c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4675d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
4676c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->post();
4677c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4678c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
4679c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
4680c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
4681c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4682c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        default:
4683c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            return BaseState::onMessageReceived(msg);
4684c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
4685c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4686c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return handled;
4687c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4688c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4689c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onConfigureComponent(
46905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg) {
46915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onConfigureComponent");
46925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
46935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(mCodec->mNode != NULL);
46945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
46955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString mime;
46965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findString("mime", &mime));
46975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
46985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mCodec->configureCodec(mime.c_str(), msg);
46995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
47005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
4701c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        ALOGE("[%s] configureCodec returning error %d",
4702c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber              mCodec->mComponentName.c_str(), err);
4703c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber
4704251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
4705c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
47065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<RefBase> obj;
4709386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    if (msg->findObject("native-window", &obj)
47105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            && strncmp("OMX.google.", mCodec->mComponentName.c_str(), 11)) {
47111173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        sp<NativeWindowWrapper> nativeWindow(
47121173118eace0e9e347cb007f0da817cee87579edGlenn Kasten                static_cast<NativeWindowWrapper *>(obj.get()));
47131173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        CHECK(nativeWindow != NULL);
47141173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        mCodec->mNativeWindow = nativeWindow->getNativeWindow();
47151ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber
47161ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber        native_window_set_scaling_mode(
47171ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                mCodec->mNativeWindow.get(),
47181ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
4719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((status_t)OK, mCodec->initNativeWindow());
4721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
47225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
47235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
4724d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatComponentConfigured);
4725e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("input-format", mCodec->mInputFormat);
4726e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("output-format", mCodec->mOutputFormat);
47275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
47285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4729c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4730c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
47315778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
47325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
47337cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::LoadedState::onCreateInputSurface(
4734ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        const sp<AMessage> & /* msg */) {
47357cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    ALOGV("onCreateInputSurface");
47367cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
47377cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<AMessage> notify = mCodec->mNotify->dup();
4738d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatInputSurfaceCreated);
47397cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
47407cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<IGraphicBufferProducer> bufferProducer;
47417cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    status_t err;
47427cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
47437cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    err = mCodec->mOMX->createInputSurface(mCodec->mNode, kPortIndexInput,
47447cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            &bufferProducer);
4745a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
4746a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    if (err == OK && mCodec->mRepeatFrameDelayUs > 0ll) {
4747a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        err = mCodec->mOMX->setInternalOption(
4748a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                mCodec->mNode,
4749a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                kPortIndexInput,
4750a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY,
4751a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                &mCodec->mRepeatFrameDelayUs,
4752a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                sizeof(mCodec->mRepeatFrameDelayUs));
4753a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
4754a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (err != OK) {
4755a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            ALOGE("[%s] Unable to configure option to repeat previous "
4756a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  "frames (err %d)",
4757a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  mCodec->mComponentName.c_str(),
4758a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  err);
4759a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
4760a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
4761a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
47622c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    if (err == OK && mCodec->mMaxPtsGapUs > 0ll) {
476394ee4b708acfa941581160b267afb79192b1d816Chong Zhang        err = mCodec->mOMX->setInternalOption(
476494ee4b708acfa941581160b267afb79192b1d816Chong Zhang                mCodec->mNode,
476594ee4b708acfa941581160b267afb79192b1d816Chong Zhang                kPortIndexInput,
476694ee4b708acfa941581160b267afb79192b1d816Chong Zhang                IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP,
476794ee4b708acfa941581160b267afb79192b1d816Chong Zhang                &mCodec->mMaxPtsGapUs,
476894ee4b708acfa941581160b267afb79192b1d816Chong Zhang                sizeof(mCodec->mMaxPtsGapUs));
476994ee4b708acfa941581160b267afb79192b1d816Chong Zhang
477094ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (err != OK) {
477194ee4b708acfa941581160b267afb79192b1d816Chong Zhang            ALOGE("[%s] Unable to configure max timestamp gap (err %d)",
477272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    mCodec->mComponentName.c_str(),
477372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    err);
47742c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
47752c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
47762c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
47772c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    if (err == OK && mCodec->mTimePerCaptureUs > 0ll
47782c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            && mCodec->mTimePerFrameUs > 0ll) {
47792c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        int64_t timeLapse[2];
47802c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[0] = mCodec->mTimePerFrameUs;
47812c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[1] = mCodec->mTimePerCaptureUs;
47822c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        err = mCodec->mOMX->setInternalOption(
47832c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                mCodec->mNode,
47842c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                kPortIndexInput,
47852c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                IOMX::INTERNAL_OPTION_TIME_LAPSE,
47862c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                &timeLapse[0],
47872c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                sizeof(timeLapse));
47882c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
47892c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (err != OK) {
47902c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            ALOGE("[%s] Unable to configure time lapse (err %d)",
47912c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    mCodec->mComponentName.c_str(),
47922c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    err);
47932c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
47942c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
479572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
479672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (err == OK && mCodec->mCreateInputBuffersSuspended) {
479772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        bool suspend = true;
479872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        err = mCodec->mOMX->setInternalOption(
479972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                mCodec->mNode,
480072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                kPortIndexInput,
480172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                IOMX::INTERNAL_OPTION_SUSPEND,
480272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                &suspend,
480372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                sizeof(suspend));
480472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
480572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
480672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("[%s] Unable to configure option to suspend (err %d)",
480794ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  mCodec->mComponentName.c_str(),
480894ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  err);
480994ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
481094ee4b708acfa941581160b267afb79192b1d816Chong Zhang    }
481194ee4b708acfa941581160b267afb79192b1d816Chong Zhang
48127cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err == OK) {
48137cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setObject("input-surface",
48147cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                new BufferProducerWrapper(bufferProducer));
48157cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else {
48167cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // Can't use mCodec->signalError() here -- MediaCodec won't forward
48177cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // the error through because it's in the "configured" state.  We
48187cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // send a kWhatInputSurfaceCreated with an error value instead.
48197cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGE("[%s] onCreateInputSurface returning error %d",
48207cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                mCodec->mComponentName.c_str(), err);
48217cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setInt32("err", err);
48227cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
48237cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->post();
48247cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
48257cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4826c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onStart() {
48275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onStart");
48285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
48295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ(mCodec->mOMX->sendCommand(
48305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
4831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
4832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->changeState(mCodec->mLoadedToIdleState);
4834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4838f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
4839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4840f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4842f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::LoadedToIdleState::stateEntered() {
48433856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
4844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4845cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    status_t err;
4846cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    if ((err = allocateBuffers()) != OK) {
484729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to allocate buffers after transitioning to IDLE state "
4848cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             "(error 0x%08x)",
4849cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             err);
4850cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
4851251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
485291bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber
485391bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber        mCodec->changeState(mCodec->mLoadedState);
4854cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    }
4855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4857f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::LoadedToIdleState::allocateBuffers() {
4858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
4859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
4861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
4862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mCodec->allocateBuffersOnPort(kPortIndexOutput);
4865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4867f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
4868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
486972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
4870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
48766507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
48776507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
48786507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
48796507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
48806507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
48816507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
48826463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatResume:
48836463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
48846463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We'll be active soon enough.
48856463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
48866463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
48876463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
48886463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatFlush:
48896463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
48906463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We haven't even started yet, so we're flushed alright...
48916463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            sp<AMessage> notify = mCodec->mNotify->dup();
4892d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
48936463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->post();
48946463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
48956463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
48966463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
4897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
4899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4902f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onOMXEvent(
4903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
4909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
4911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting),
4912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
4913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mIdleToExecutingState);
4915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4926f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
4927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4930f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToExecutingState::stateEntered() {
49313856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
4932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4934f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
4935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
493672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
4937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4943d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatResume:
4944d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
4945d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We'll be active soon enough.
4946d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
4947d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
4948d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
4949d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatFlush:
4950d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
4951d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We haven't even started yet, so we're flushed alright...
4952d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4953d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
4954d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->post();
4955d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
4956d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
4957d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
4958d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
49596507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
49606507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
49616507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
49626507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
49636507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
49646507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
4965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
4967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4970f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onOMXEvent(
4971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateExecuting);
4977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mExecutingState->resume();
4979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingState);
4980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4991f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingState::ExecutingState(ACodec *codec)
4992349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    : BaseState(codec),
4993349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber      mActive(false) {
4994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4996f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
4997ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
4998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
4999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5001054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputMetaBuffers() {
5002054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // submit as many buffers as there are input buffers with the codec
5003054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // in case we are in port reconfiguring
5004054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
5005054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
5006054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5007054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) {
5008054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            if (mCodec->submitOutputMetaDataBuffer() != OK)
5009054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                break;
5010054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
5011054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
50124dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
50134dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
50144dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
5015054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
5016054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5017054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitRegularOutputBuffers() {
5018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
5019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
5020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mCodec->mNativeWindow != NULL) {
5022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(info->mStatus == BufferInfo::OWNED_BY_US
5023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
5024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
5026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                continue;
5027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
5029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
5030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
50323856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] calling fillBuffer %p",
5033349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str(), info->mBufferID);
5034349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
5036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
5037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
5039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5042054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputBuffers() {
5043c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar    submitRegularOutputBuffers();
5044054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mCodec->mStoreMetaDataInOutputBuffers) {
5045054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        submitOutputMetaBuffers();
5046054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
5047054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
5048054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5049f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::resume() {
5050349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    if (mActive) {
50513856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] We're already active, no need to resume.",
5052349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str());
5053349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5054349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        return;
5055349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    }
5056349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    submitOutputBuffers();
5058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
50593cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    // Post all available input buffers
5060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_GT(mCodec->mBuffers[kPortIndexInput].size(), 0u);
50613cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); i++) {
50623cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
50633cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_US) {
50643cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar            postFillThisBuffer(info);
50653cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        }
50663cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    }
5067349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5068349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    mActive = true;
5069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5071f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::stateEntered() {
50723856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
5073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->processDeferredMessages();
5075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5077f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
5078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5081f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5083c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
5084c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
5085c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
5086c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5087c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mShutdownInProgress = true;
508854b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
5089c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mKeepComponentAllocated = keepComponentAllocated;
5090c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5091349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
5092349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
5094f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
5095f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
5096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingToIdleState);
5098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
51057a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong            ALOGV("[%s] ExecutingState flushing now "
5106d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                 "(codec owns %d/%d input, %d/%d output).",
5107d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mComponentName.c_str(),
5108d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
5109d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexInput].size(),
5110d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
5111d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexOutput].size());
5112d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
5113349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
5114349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
5116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandFlush, OMX_ALL),
5117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
5118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mFlushingState);
5120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatResume:
5125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            resume();
5127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5132496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
5133496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
5134496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            status_t err = mCodec->requestIDRFrame();
5135496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            if (err != OK) {
5136496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                ALOGW("Requesting an IDR frame failed.");
5137496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            }
5138496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5139496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            handled = true;
5140496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
5141496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
5142496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5143a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
5144a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
5145a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
5146a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
5147a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5148a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = mCodec->setParameters(params);
5149a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5150a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> reply;
5151a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            if (msg->findMessage("reply", &reply)) {
5152a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->setInt32("err", err);
5153a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->post();
5154a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            }
5155a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5156a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            handled = true;
5157a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
5158a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
5159a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
51607cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
51617cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
51626507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
51637cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
51647cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
51657cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
51667cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
51674dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
51684dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        case kWhatSubmitOutputMetaDataBufferIfEOS:
51694dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        {
51704dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            if (mCodec->mPortEOS[kPortIndexInput] &&
51714dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    !mCodec->mPortEOS[kPortIndexOutput]) {
51724dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                status_t err = mCodec->submitOutputMetaDataBuffer();
51734dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                if (err == OK) {
51744dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
51754dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                }
51764dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            }
51774dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            return true;
51784dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        }
51794dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
5180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5188a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t ACodec::setParameters(const sp<AMessage> &params) {
5189a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    int32_t videoBitrate;
5190530fdbdc1b5491f3fbf172752834d1515701e142Lajos Molnar    if (params->findInt32("video-bitrate", &videoBitrate)) {
5191a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        OMX_VIDEO_CONFIG_BITRATETYPE configParams;
5192a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        InitOMXParams(&configParams);
5193a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nPortIndex = kPortIndexOutput;
5194a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nEncodeBitrate = videoBitrate;
5195a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5196a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        status_t err = mOMX->setConfig(
5197a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                mNode,
5198a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                OMX_IndexConfigVideoBitrate,
5199a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                &configParams,
5200a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                sizeof(configParams));
5201a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5202a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        if (err != OK) {
5203a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
5204a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                   videoBitrate, err);
5205a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5206a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            return err;
5207a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
5208a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    }
5209a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
521072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    int64_t skipFramesBeforeUs;
521172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (params->findInt64("skip-frames-before", &skipFramesBeforeUs)) {
521272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        status_t err =
521372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mOMX->setInternalOption(
521472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     mNode,
521572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     kPortIndexInput,
521672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     IOMX::INTERNAL_OPTION_START_TIME,
521772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     &skipFramesBeforeUs,
521872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     sizeof(skipFramesBeforeUs));
521972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
522072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
522172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("Failed to set parameter 'skip-frames-before' (err %d)", err);
522272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            return err;
522372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
522472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
522572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
5226e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    int32_t dropInputFrames;
5227e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    if (params->findInt32("drop-input-frames", &dropInputFrames)) {
5228e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        bool suspend = dropInputFrames != 0;
5229e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
5230b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err =
5231b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            mOMX->setInternalOption(
5232e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     mNode,
5233e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     kPortIndexInput,
5234e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     IOMX::INTERNAL_OPTION_SUSPEND,
5235e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     &suspend,
5236b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber                     sizeof(suspend));
5237b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
5238b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
5239b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err);
5240b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
5241b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
5242b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    }
5243b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
5244b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    int32_t dummy;
5245b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    if (params->findInt32("request-sync", &dummy)) {
5246b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err = requestIDRFrame();
5247b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
5248b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
5249b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Requesting a sync frame failed w/ err %d", err);
5250b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
5251b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
5252e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    }
5253e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
5254a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return OK;
5255a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
5256a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
52576507d14c6d10f93d390de62b9eed267f9b544985Andy McFaddenvoid ACodec::onSignalEndOfInputStream() {
52586507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    sp<AMessage> notify = mNotify->dup();
5259d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatSignaledInputEOS);
52606507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
52616507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    status_t err = mOMX->signalEndOfInputStream(mNode);
52626507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    if (err != OK) {
52636507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        notify->setInt32("err", err);
52646507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    }
52656507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->post();
52666507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden}
52676507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
5268f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onOMXEvent(
5269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventPortSettingsChanged:
5272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
5274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
527531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
5276054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mCodec->mMetaDataBuffersToSubmit = 0;
5277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
5278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
5279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_CommandPortDisable, kPortIndexOutput),
5280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
5281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5282349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                mCodec->freeOutputBuffersNotOwnedByComponent();
5283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
528531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            } else if (data2 == OMX_IndexConfigCommonOutputCrop) {
528631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
5287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
52883856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08lx",
5289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->mComponentName.c_str(), data2);
5290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventBufferFlag:
5296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5307f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
5308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ACodec *codec)
5309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5312f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
5313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
5314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput) {
5315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return FREE_BUFFERS;
5316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
5319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
5321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5323f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onMessageReceived(
5324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
5325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5330349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case kWhatResume:
5331e6eea3a6b6e0cf92287ec1ceb8350f201d17e1acPer Persson        case kWhatSetParameters:
5332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5333349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            if (msg->what() == kWhatResume) {
53343856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
5335349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            }
5336349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
5338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5350f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::OutputPortSettingsChangedState::stateEntered() {
53513856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now handling output port settings change",
5352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mCodec->mComponentName.c_str());
5353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5355f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onOMXEvent(
5356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
5361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
5362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
53633856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now disabled.",
5364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
5365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mCodec->mBuffers[kPortIndexOutput].isEmpty());
5367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mDealer[kPortIndexOutput].clear();
5368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
5370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput),
5371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
5372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5373cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                status_t err;
5374cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                if ((err = mCodec->allocateBuffersOnPort(
5375cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                                kPortIndexOutput)) != OK) {
537629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("Failed to allocate output port buffers after "
5377cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         "port reconfiguration (error 0x%08x)",
5378cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         err);
5379cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
5380251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5381d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
5382755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // This is technically not correct, but appears to be
5383755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the only way to free the component instance.
5384755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // Controlled transitioning from excecuting->idle
5385755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // and idle->loaded seem impossible probably because
5386755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the output port never finishes re-enabling.
5387755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mShutdownInProgress = true;
5388755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mKeepComponentAllocated = false;
5389755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->changeState(mCodec->mLoadedState);
5390cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                }
5391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
5393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
5394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
5395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
539631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
539731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
53983856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now reenabled.",
5399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
5400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5401349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                if (mCodec->mExecutingState->active()) {
5402349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    mCodec->mExecutingState->submitOutputBuffers();
5403349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                }
5404349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mExecutingState);
5406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
5408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
5411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
5415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5420f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
54215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : BaseState(codec),
54225778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mComponentNowIdle(false) {
5423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5425f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
5426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
5432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
5433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
5434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
5440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5453f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::stateEntered() {
54543856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
545531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
54565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mComponentNowIdle = false;
545731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mCodec->mSentFormat = false;
5458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5460f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onOMXEvent(
5461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
5466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
5467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
54685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mComponentNowIdle = true;
54695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            changeStateIfWeOwnAllBuffers();
5471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5475349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
5476349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventBufferFlag:
5477349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
5478349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We're shutting down and don't care about this anymore.
5479349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
5480349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
5481349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
54860af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
5487f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
54885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
5489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->sendCommand(
5490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded),
5491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
5492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexInput), (status_t)OK);
5494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexOutput), (status_t)OK);
5495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
54960167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown)
54970167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && mCodec->mNativeWindow != NULL) {
5498bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // We push enough 1x1 blank buffers to ensure that one of
5499bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // them has made it to the display.  This allows the OMX
5500bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // component teardown to zero out any protected buffers
5501bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // without the risk of scanning out one of those buffers.
5502bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            mCodec->pushBlankBuffersToNativeWindow();
5503bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
5504bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
5505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mIdleToLoadedState);
5506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5509f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onInputBufferFilled(
5510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
5511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
5512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
5514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5516f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onOutputBufferDrained(
5517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
5518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
5519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
5521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5525f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
5526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5529f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
5530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
5536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
5544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
5545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
5546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5557f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToLoadedState::stateEntered() {
55583856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
5559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5561f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onOMXEvent(
5562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
5567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateLoaded);
5568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5569c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->changeState(mCodec->mLoadedState);
5570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5581f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::FlushingState::FlushingState(ACodec *codec)
5582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5585f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::stateEntered() {
55863856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
5587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
5589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5591f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
5592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
5598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing this right now.
5604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5616f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onOMXEvent(
5617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
56187a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] FlushingState onOMXEvent(%d,%ld)",
5619d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            mCodec->mComponentName.c_str(), event, data1);
5620d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
5621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandFlush);
5625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
5627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(!mFlushComplete[data2]);
5628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mFlushComplete[data2] = true;
5629e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber
5630e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                if (mFlushComplete[kPortIndexInput]
5631e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                        && mFlushComplete[kPortIndexOutput]) {
5632e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                    changeStateIfWeOwnAllBuffers();
5633e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                }
5634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
5635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, OMX_ALL);
5636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexInput]);
5637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexOutput]);
5638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                changeStateIfWeOwnAllBuffers();
5640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5645349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
5646349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
5647349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec->id());
5648349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("type", omx_message::EVENT);
5649609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            msg->setInt32("node", mCodec->mNode);
5650349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("event", event);
5651349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data1", data1);
5652349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data2", data2);
5653349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
56543856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
5655349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                 mCodec->mComponentName.c_str());
5656349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5657349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mCodec->deferMessage(msg);
5658349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5659349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
5660349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
5661349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
5667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5669f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
5670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
5671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
5673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5675f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
5676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
5677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
5679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5681f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
5682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mFlushComplete[kPortIndexInput]
5683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mFlushComplete[kPortIndexOutput]
5684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mCodec->allYourBuffersAreBelongToUs()) {
56857e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // We now own all buffers except possibly those still queued with
56867e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // the native window for rendering. Let's get those back as well.
56877e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
56887e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
5689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
5690d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatFlushCompleted);
5691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->post();
5692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->mPortEOS[kPortIndexInput] =
5694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mPortEOS[kPortIndexOutput] = false;
5695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5696dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber        mCodec->mInputEOSResult = OK;
5697dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
5698f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        if (mCodec->mSkipCutBuffer != NULL) {
5699f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen            mCodec->mSkipCutBuffer->clear();
5700f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        }
5701f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen
5702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mExecutingState);
5703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
5707