ACodec.cpp revision 97827bd7c7e64dec22c8fe0f9e734a3c432ad7ee
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>
35f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
367cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden#include <media/stagefright/BufferProducerWrapper.h>
37afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber#include <media/stagefright/MediaCodecList.h>
38f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaDefs.h>
391173118eace0e9e347cb007f0da817cee87579edGlenn Kasten#include <media/stagefright/NativeWindowWrapper.h>
40f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/OMXClient.h>
411065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber#include <media/stagefright/OMXCodec.h>
42f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
433a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber#include <media/hardware/HardwareAPI.h>
443a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
4597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu#include <OMX_AudioExt.h>
464154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev#include <OMX_VideoExt.h>
47f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <OMX_Component.h>
4897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu#include <OMX_IndexExt.h>
49f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
50496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#include "include/avc_utils.h"
51496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
52f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android {
53f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
54251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// OMX errors are directly mapped into status_t range if
55251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// there is no corresponding MediaError status code.
56251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Use the statusFromOMXError(int32_t omxError) function.
57251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung//
58251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Currently this is a direct map.
59251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// See frameworks/native/include/media/openmax/OMX_Core.h
60251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung//
61251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Vendor OMX errors     from 0x90000000 - 0x9000FFFF
62251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Extension OMX errors  from 0x8F000000 - 0x90000000
63251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Standard OMX errors   from 0x80001000 - 0x80001024 (0x80001024 current)
64251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung//
65251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
66251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// returns true if err is a recognized OMX error code.
67251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// as OMX error is OMX_S32, this is an int32_t type
68251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hungstatic inline bool isOMXError(int32_t err) {
69251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    return (ERROR_CODEC_MIN <= err && err <= ERROR_CODEC_MAX);
70251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung}
71251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
72251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// converts an OMX error to a status_t
73251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hungstatic inline status_t statusFromOMXError(int32_t omxError) {
74251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    switch (omxError) {
75251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case OMX_ErrorInvalidComponentName:
76251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case OMX_ErrorComponentNotFound:
77251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return NAME_NOT_FOUND; // can trigger illegal argument error for provided names.
78251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    default:
79251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return isOMXError(omxError) ? omxError : 0; // no translation required
80251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
81251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung}
82251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
83251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// checks and converts status_t to a non-side-effect status_t
84251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hungstatic inline status_t makeNoSideEffectStatus(status_t err) {
85251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    switch (err) {
86251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // the following errors have side effects and may come
87251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // from other code modules. Remap for safety reasons.
88251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case INVALID_OPERATION:
89251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case DEAD_OBJECT:
90251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return UNKNOWN_ERROR;
91251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    default:
92251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return err;
93251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
94251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung}
95251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
96f933441648ef6a71dee783d733aac17b9508b452Andreas Hubertemplate<class T>
97f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic void InitOMXParams(T *params) {
98f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nSize = sizeof(T);
99f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nVersionMajor = 1;
100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nVersionMinor = 0;
101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nRevision = 0;
102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nStep = 0;
103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
105f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct CodecObserver : public BnOMXObserver {
106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CodecObserver() {}
107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void setNotificationMessage(const sp<AMessage> &msg) {
109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mNotify = msg;
110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // from IOMXObserver
113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onMessage(const omx_message &omx_msg) {
114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> msg = mNotify->dup();
115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->setInt32("type", omx_msg.type);
117609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        msg->setInt32("node", omx_msg.node);
118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        switch (omx_msg.type) {
120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::EVENT:
121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("event", omx_msg.u.event_data.event);
123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("data1", omx_msg.u.event_data.data1);
124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("data2", omx_msg.u.event_data.data2);
125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::EMPTY_BUFFER_DONE:
129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
130609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                msg->setInt32("buffer", omx_msg.u.buffer_data.buffer);
131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::FILL_BUFFER_DONE:
135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
136609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                msg->setInt32(
137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "buffer", omx_msg.u.extended_buffer_data.buffer);
138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "range_offset",
140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.range_offset);
141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "range_length",
143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.range_length);
144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "flags",
146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.flags);
147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt64(
148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "timestamp",
149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.timestamp);
150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            default:
154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                TRESPASS();
155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->post();
159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
161f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual ~CodecObserver() {}
163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
164f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> mNotify;
166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(CodecObserver);
168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
172f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::BaseState : public AState {
173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState(ACodec *codec, const sp<AState> &parentState = NULL);
174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
175f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    enum PortMode {
177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        KEEP_BUFFERS,
178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        RESUBMIT_BUFFERS,
179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        FREE_BUFFERS,
180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ACodec *mCodec;
183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void postFillThisBuffer(BufferInfo *info);
194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
195f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXMessage(const sp<AMessage> &msg);
197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXEmptyBufferDone(IOMX::buffer_id bufferID);
199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXFillBufferDone(
201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID,
202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            size_t rangeOffset, size_t rangeLength,
203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            OMX_U32 flags,
204784e24e386b088c05d653ab482f2e95cb53e3d01Andy Hung            int64_t timeUs);
205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void getMoreInputDataIfPossible();
207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(BaseState);
209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
213ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberstruct ACodec::DeathNotifier : public IBinder::DeathRecipient {
214ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    DeathNotifier(const sp<AMessage> &notify)
215ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        : mNotify(notify) {
216ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
217ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
218ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual void binderDied(const wp<IBinder> &) {
219ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mNotify->post();
220ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
221ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
222ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprotected:
223ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual ~DeathNotifier() {}
224ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
225ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprivate:
226ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> mNotify;
227ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
228ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(DeathNotifier);
229ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber};
230ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
231f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::UninitializedState : public ACodec::BaseState {
232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    UninitializedState(ACodec *codec);
233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
234f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
236c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
238f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void onSetup(const sp<AMessage> &msg);
240c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onAllocateComponent(const sp<AMessage> &msg);
241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
242ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<DeathNotifier> mDeathNotifier;
243ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(UninitializedState);
245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
249c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberstruct ACodec::LoadedState : public ACodec::BaseState {
250c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    LoadedState(ACodec *codec);
251c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
252c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprotected:
253c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
254c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
255c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
256c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprivate:
257c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    friend struct ACodec::UninitializedState;
258c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
259c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onConfigureComponent(const sp<AMessage> &msg);
2607cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    void onCreateInputSurface(const sp<AMessage> &msg);
261c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onStart();
262c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onShutdown(bool keepComponentAllocated);
263c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
264c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedState);
265c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber};
266c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
267c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
268c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
269f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::LoadedToIdleState : public ACodec::BaseState {
270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    LoadedToIdleState(ACodec *codec);
271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
272f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
277f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t allocateBuffers();
279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedToIdleState);
281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
285f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToExecutingState : public ACodec::BaseState {
286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToExecutingState(ACodec *codec);
287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
288f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
293f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToExecutingState);
295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
299f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingState : public ACodec::BaseState {
300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingState(ACodec *codec);
301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
302054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitRegularOutputBuffers();
303054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitOutputMetaBuffers();
304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void submitOutputBuffers();
305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Submit output buffers to the decoder, submit input buffers to client
307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // to fill with data.
308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void resume();
309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
310349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    // Returns true iff input and output buffers are in play.
311349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool active() const { return mActive; }
312349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
313f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
320f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
321349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool mActive;
322349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingState);
324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
328f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::OutputPortSettingsChangedState : public ACodec::BaseState {
329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OutputPortSettingsChangedState(ACodec *codec);
330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
331f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
338f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(OutputPortSettingsChangedState);
340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
344f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingToIdleState : public ACodec::BaseState {
345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingToIdleState(ACodec *codec);
346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
347f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
356f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool mComponentNowIdle;
3605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingToIdleState);
362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
366f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToLoadedState : public ACodec::BaseState {
367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToLoadedState(ACodec *codec);
368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
369f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
375f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToLoadedState);
377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
381f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::FlushingState : public ACodec::BaseState {
382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    FlushingState(ACodec *codec);
383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
384f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
393f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool mFlushComplete[2];
395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(FlushingState);
399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
403f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ACodec()
404afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    : mQuirks(0),
405609b815a3131d22da38b2f452faa9f89daad4039Andy Hung      mNode(0),
4065778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mSentFormat(false),
407c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber      mIsEncoder(false),
408308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang      mUseMetadataOnEncoderOutput(false),
4099806555d3930be43e11106281dee354820ac1c88Andreas Huber      mShutdownInProgress(false),
41054b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar      mExplicitShutdown(false),
4119806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderDelay(0),
4129806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderPadding(0),
413e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang      mRotationDegrees(0),
4149806555d3930be43e11106281dee354820ac1c88Andreas Huber      mChannelMaskPresent(false),
415054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mChannelMask(0),
416054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mDequeueCounter(0),
417054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mStoreMetaDataInOutputBuffers(false),
418a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber      mMetaDataBuffersToSubmit(0),
41994ee4b708acfa941581160b267afb79192b1d816Chong Zhang      mRepeatFrameDelayUs(-1ll),
4202c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang      mMaxPtsGapUs(-1ll),
4212c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang      mTimePerFrameUs(-1ll),
422609b815a3131d22da38b2f452faa9f89daad4039Andy Hung      mTimePerCaptureUs(-1ll),
42372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang      mCreateInputBuffersSuspended(false) {
424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mUninitializedState = new UninitializedState(this);
425c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mLoadedState = new LoadedState(this);
426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mLoadedToIdleState = new LoadedToIdleState(this);
427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToExecutingState = new IdleToExecutingState(this);
428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingState = new ExecutingState(this);
429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOutputPortSettingsChangedState =
431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        new OutputPortSettingsChangedState(this);
432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingToIdleState = new ExecutingToIdleState(this);
434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToLoadedState = new IdleToLoadedState(this);
435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushingState = new FlushingState(this);
436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
438dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber    mInputEOSResult = OK;
439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeState(mUninitializedState);
441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
443f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::~ACodec() {
444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
446f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::setNotificationMessage(const sp<AMessage> &msg) {
447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mNotify = msg;
448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
450f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::initiateSetup(const sp<AMessage> &msg) {
451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setWhat(kWhatSetup);
452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setTarget(id());
453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
456a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Hubervoid ACodec::signalSetParameters(const sp<AMessage> &params) {
457a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    sp<AMessage> msg = new AMessage(kWhatSetParameters, id());
458a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->setMessage("params", params);
459a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->post();
460a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
461a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4625778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateAllocateComponent(const sp<AMessage> &msg) {
4635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatAllocateComponent);
4645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
4655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4665778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4685778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateConfigureComponent(const sp<AMessage> &msg) {
4695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatConfigureComponent);
4705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
4715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4725778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4747cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::initiateCreateInputSurface() {
4757cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    (new AMessage(kWhatCreateInputSurface, id()))->post();
4767cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
4777cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4787cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::signalEndOfInputStream() {
4797cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    (new AMessage(kWhatSignalEndOfInputStream, id()))->post();
4807cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
4817cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4825778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateStart() {
4835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    (new AMessage(kWhatStart, id()))->post();
4845778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
486f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalFlush() {
4877a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] signalFlush", mComponentName.c_str());
488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatFlush, id()))->post();
489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
491f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalResume() {
492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatResume, id()))->post();
493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
495c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::initiateShutdown(bool keepComponentAllocated) {
496c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> msg = new AMessage(kWhatShutdown, id());
497c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->setInt32("keepComponentAllocated", keepComponentAllocated);
498c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->post();
499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
501496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubervoid ACodec::signalRequestIDRFrame() {
502496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    (new AMessage(kWhatRequestIDRFrame, id()))->post();
503496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
504496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5054dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
5064dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// Some codecs may return input buffers before having them processed.
5074dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// This causes a halt if we already signaled an EOS on the input
5084dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// port.  For now keep submitting an output buffer if there was an
5094dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// EOS on the input port, but not yet on the output port.
5104dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnarvoid ACodec::signalSubmitOutputMetaDataBufferIfEOS_workaround() {
5114dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    if (mPortEOS[kPortIndexInput] && !mPortEOS[kPortIndexOutput] &&
5124dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            mMetaDataBuffersToSubmit > 0) {
5134dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        (new AMessage(kWhatSubmitOutputMetaDataBufferIfEOS, id()))->post();
5144dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    }
5154dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar}
5164dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
517f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mDealer[portIndex] == NULL);
521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mBuffers[portIndex].isEmpty());
522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
525054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (mStoreMetaDataInOutputBuffers) {
526054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputMetaDataBuffers();
527054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
528054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputBuffersFromNativeWindow();
529054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
5305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
5315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
5325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
5335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = portIndex;
534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
5365778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err == OK) {
539609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGV("[%s] Allocating %u buffers of size %u on %s port",
5405778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mComponentName.c_str(),
5415778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    def.nBufferCountActual, def.nBufferSize,
5425778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    portIndex == kPortIndexInput ? "input" : "output");
543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            size_t totalSize = def.nBufferCountActual * def.nBufferSize;
5455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
5485778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
5495778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(mem.get() != NULL);
550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
551ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                BufferInfo info;
552ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                info.mStatus = BufferInfo::OWNED_BY_US;
553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
554afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                uint32_t requiresAllocateBufferBit =
555afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                    (portIndex == kPortIndexInput)
556afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        ? OMXCodec::kRequiresAllocateBufferOnInputPorts
557afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        : OMXCodec::kRequiresAllocateBufferOnOutputPorts;
5581065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
559308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                if ((portIndex == kPortIndexInput && (mFlags & kFlagIsSecure))
560308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        || mUseMetadataOnEncoderOutput) {
561ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    mem.clear();
562ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
563ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    void *ptr;
564ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->allocateBuffer(
565ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, def.nBufferSize, &info.mBufferID,
566ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            &ptr);
567ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
568308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    int32_t bufSize = mUseMetadataOnEncoderOutput ?
569308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                            (4 + sizeof(buffer_handle_t)) : def.nBufferSize;
570308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
571308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    info.mData = new ABuffer(ptr, bufSize);
572ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                } else if (mQuirks & requiresAllocateBufferBit) {
5735778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    err = mOMX->allocateBufferWithBackup(
574ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, mem, &info.mBufferID);
5755778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
576ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->useBuffer(mNode, portIndex, mem, &info.mBufferID);
577ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                }
578ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
579ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                if (mem != NULL) {
580ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    info.mData = new ABuffer(mem->pointer(), def.nBufferSize);
5815778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
5821065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
5835778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mBuffers[portIndex].push(info);
5841065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            }
5851065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
5865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
5895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
5905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> notify = mNotify->dup();
593d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatBuffersAllocated);
5945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("portIndex", portIndex);
596eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
597eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    sp<PortDescription> desc = new PortDescription;
598eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
600eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        const BufferInfo &info = mBuffers[portIndex][i];
6015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
602eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        desc->addBuffer(info.mBufferID, info.mData);
603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
605eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    notify->setObject("portDesc", desc);
6065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->post();
6075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
611054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::configureOutputBuffersFromNativeWindow(
612054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 *bufferCount, OMX_U32 *bufferSize,
613054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 *minUndequeuedBuffers) {
614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = kPortIndexOutput;
617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffers_geometry(
626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameWidth,
628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameHeight,
629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.eColorFormat);
630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
63229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffers_geometry failed: %s (%d)",
633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                strerror(-err), -err);
634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
637e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang    if (mRotationDegrees != 0) {
638e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        uint32_t transform = 0;
639e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        switch (mRotationDegrees) {
640e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            case 0: transform = 0; break;
641e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            case 90: transform = HAL_TRANSFORM_ROT_90; break;
642e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            case 180: transform = HAL_TRANSFORM_ROT_180; break;
643e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            case 270: transform = HAL_TRANSFORM_ROT_270; break;
644e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            default: transform = 0; break;
645e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        }
646e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang
647e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        if (transform > 0) {
648e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            err = native_window_set_buffers_transform(
649e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang                    mNativeWindow.get(), transform);
650e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            if (err != 0) {
651e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang                ALOGE("native_window_set_buffers_transform failed: %s (%d)",
652e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang                        strerror(-err), -err);
653e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang                return err;
654e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            }
655e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        }
656e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang    }
657e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang
658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Set up the native window.
6593c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    OMX_U32 usage = 0;
6603c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
6613c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    if (err != 0) {
6625ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("querying usage flags from OMX IL component failed: %d", err);
6633c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        // XXX: Currently this error is logged, but not fatal.
6643c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        usage = 0;
6653c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    }
6663c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis
667bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (mFlags & kFlagIsSecure) {
668bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        usage |= GRALLOC_USAGE_PROTECTED;
669bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
670bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
671bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // Make sure to check whether either Stagefright or the video decoder
672bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // requested protected buffers.
673bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (usage & GRALLOC_USAGE_PROTECTED) {
674bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Verify that the ANativeWindow sends images directly to
675bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // SurfaceFlinger.
676bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        int queuesToNativeWindow = 0;
677bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->query(
678bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                mNativeWindow.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
679bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                &queuesToNativeWindow);
680bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != 0) {
681bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error authenticating native window: %d", err);
682bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
683bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
684bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (queuesToNativeWindow != 1) {
685bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("native window could not be authenticated");
686bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return PERMISSION_DENIED;
687bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
688bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
689bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_usage(
691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
6923c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis            usage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP);
693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
69529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err);
696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
699054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *minUndequeuedBuffers = 0;
700258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    err = mNativeWindow->query(
701258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
702054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (int *)minUndequeuedBuffers);
703258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
704258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    if (err != 0) {
70529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
706258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                strerror(-err), -err);
707258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        return err;
708258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
709258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
710e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // FIXME: assume that surface is controlled by app (native window
711e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // returns the number for the case when surface is not controlled by app)
7121faa41704e0b976e546321effcb09a85767d51baLajos Molnar    // FIXME2: This means that minUndeqeueudBufs can be 1 larger than reported
7131faa41704e0b976e546321effcb09a85767d51baLajos Molnar    // For now, try to allocate 1 more buffer, but don't fail if unsuccessful
714e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar
715e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // Use conservative allocation while also trying to reduce starvation
716e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //
717e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // 1. allocate at least nBufferCountMin + minUndequeuedBuffers - that is the
718e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //    minimum needed for the consumer to be able to work
719e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // 2. try to allocate two (2) additional buffers to reduce starvation from
720e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //    the consumer
7211faa41704e0b976e546321effcb09a85767d51baLajos Molnar    //    plus an extra buffer to account for incorrect minUndequeuedBufs
7221faa41704e0b976e546321effcb09a85767d51baLajos Molnar    for (OMX_U32 extraBuffers = 2 + 1; /* condition inside loop */; extraBuffers--) {
723e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        OMX_U32 newBufferCount =
724e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            def.nBufferCountMin + *minUndequeuedBuffers + extraBuffers;
725258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        def.nBufferCountActual = newBufferCount;
726258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        err = mOMX->setParameter(
727258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
728258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
729e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        if (err == OK) {
730e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            *minUndequeuedBuffers += extraBuffers;
731e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            break;
732e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        }
733e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar
734609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGW("[%s] setting nBufferCountActual to %u failed: %d",
735e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar                mComponentName.c_str(), newBufferCount, err);
736e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        /* exit condition */
737e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        if (extraBuffers == 0) {
738258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            return err;
739258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        }
740258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
741258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffer_count(
743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(), def.nBufferCountActual);
744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
74629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                -err);
748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
751054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferCount = def.nBufferCountActual;
752054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferSize =  def.nBufferSize;
753054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
754054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
755054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
756054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputBuffersFromNativeWindow() {
757054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
758054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
759054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
760054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
761054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
762e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    mNumUndequeuedBuffers = minUndequeuedBuffers;
763054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
764609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Allocating %u buffers from a native window of size %u on "
765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         "output port",
766054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount, bufferSize);
767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Dequeue buffers and send them to OMX
769054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
7708ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev        ANativeWindowBuffer *buf;
7711e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
77329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
775f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
77874006804065941841883c4b46ee785070164023fJamie Gennis        BufferInfo info;
77974006804065941841883c4b46ee785070164023fJamie Gennis        info.mStatus = BufferInfo::OWNED_BY_US;
780054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(NULL /* data */, bufferSize /* capacity */);
78174006804065941841883c4b46ee785070164023fJamie Gennis        info.mGraphicBuffer = graphicBuffer;
78274006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].push(info);
78374006804065941841883c4b46ee785070164023fJamie Gennis
784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferId;
785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &bufferId);
787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
788609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGE("registering GraphicBuffer %u with OMX IL component failed: "
78974006804065941841883c4b46ee785070164023fJamie Gennis                 "%d", i, err);
790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
79374006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
79474006804065941841883c4b46ee785070164023fJamie Gennis
795609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGV("[%s] Registered graphic buffer with ID %u (pointer = %p)",
796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mComponentName.c_str(),
797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             bufferId, graphicBuffer.get());
798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelStart;
801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelEnd;
802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // If an error occurred while dequeuing we need to cancel any buffers
805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // that were dequeued.
806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelStart = 0;
80774006804065941841883c4b46ee785070164023fJamie Gennis        cancelEnd = mBuffers[kPortIndexOutput].size();
808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
809054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // Return the required minimum undequeued buffers to the native window.
810054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelStart = bufferCount - minUndequeuedBuffers;
811054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelEnd = bufferCount;
812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
8163fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        status_t error = cancelBufferToNativeWindow(info);
8173fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        if (err == 0) {
8183fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia            err = error;
8193fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        }
820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
825054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputMetaDataBuffers() {
826054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
827054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
828054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
829054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
830054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
831e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    mNumUndequeuedBuffers = minUndequeuedBuffers;
832054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
833609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Allocating %u meta buffers on output port",
834054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount);
835054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
836054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    size_t totalSize = bufferCount * 8;
837054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mDealer[kPortIndexOutput] = new MemoryDealer(totalSize, "ACodec");
838054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
839054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // Dequeue buffers and send them to OMX
840054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
841054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo info;
842054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
843054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mGraphicBuffer = NULL;
844054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mDequeuedAt = mDequeueCounter;
845054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
846054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        sp<IMemory> mem = mDealer[kPortIndexOutput]->allocate(
847054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                sizeof(struct VideoDecoderOutputMetaData));
848054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(mem.get() != NULL);
849054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(mem->pointer(), mem->size());
850054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
851054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // we use useBuffer for metadata regardless of quirks
852054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        err = mOMX->useBuffer(
853054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mNode, kPortIndexOutput, mem, &info.mBufferID);
854054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
855054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        mBuffers[kPortIndexOutput].push(info);
856054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
857609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGV("[%s] allocated meta buffer with ID %u (pointer = %p)",
858054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mComponentName.c_str(), info.mBufferID, mem->pointer());
859054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
860054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
861054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mMetaDataBuffersToSubmit = bufferCount - minUndequeuedBuffers;
862054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
863054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
864054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
865054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::submitOutputMetaDataBuffer() {
866054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mStoreMetaDataInOutputBuffers);
867054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mMetaDataBuffersToSubmit == 0)
868054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return OK;
869054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
870054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *info = dequeueBufferFromNativeWindow();
871054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (info == NULL)
872054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return ERROR_IO;
873054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
874609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] submitting output meta buffer ID %u for graphic buffer %p",
875054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          mComponentName.c_str(), info->mBufferID, info->mGraphicBuffer.get());
876054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
877054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    --mMetaDataBuffersToSubmit;
878054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK_EQ(mOMX->fillBuffer(mNode, info->mBufferID),
879054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             (status_t)OK);
880054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
881054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
882054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return OK;
883054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
884054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
885f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
888609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Calling cancelBuffer on buffer %u",
889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mComponentName.c_str(), info->mBufferID);
890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int err = mNativeWindow->cancelBuffer(
8921e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        mNativeWindow.get(), info->mGraphicBuffer.get(), -1);
893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8943fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia    ALOGW_IF(err != 0, "[%s] can not return buffer %u to native window",
8953fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia            mComponentName.c_str(), info->mBufferID);
896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8993fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia    return err;
900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
902f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
9038ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev    ANativeWindowBuffer *buf;
9041e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    int fenceFd = -1;
905054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mNativeWindow.get() != NULL);
9061e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    if (native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf) != 0) {
90729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("dequeueBuffer failed.");
908c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber        return NULL;
909c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
911054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *oldest = NULL;
912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
916054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mGraphicBuffer != NULL &&
917054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            info->mGraphicBuffer->handle == buf->handle) {
918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus,
919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (int)BufferInfo::OWNED_BY_NATIVE_WINDOW);
920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
925054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
926054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW &&
927054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (oldest == NULL ||
928054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             // avoid potential issues from counter rolling over
929054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mDequeueCounter - info->mDequeuedAt >
930054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    mDequeueCounter - oldest->mDequeuedAt)) {
931054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            oldest = info;
932054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
933054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
934054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
935054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (oldest) {
936054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(mStoreMetaDataInOutputBuffers);
937054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
938054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // discard buffer in LRU info and replace with new buffer
939054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mGraphicBuffer = new GraphicBuffer(buf, false);
940054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mStatus = BufferInfo::OWNED_BY_US;
941054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
942d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        mOMX->updateGraphicBufferInMeta(
943d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                mNode, kPortIndexOutput, oldest->mGraphicBuffer,
944d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                oldest->mBufferID);
945054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
946d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        VideoDecoderOutputMetaData *metaData =
947d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar            reinterpret_cast<VideoDecoderOutputMetaData *>(
948d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                    oldest->mData->base());
949d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        CHECK_EQ(metaData->eType, kMetadataBufferTypeGrallocSource);
950d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar
951d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
952054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                oldest - &mBuffers[kPortIndexOutput][0],
953054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mDequeueCounter - oldest->mDequeuedAt,
954d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                metaData->pHandle,
955d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                oldest->mGraphicBuffer->handle, oldest->mData->base());
956054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
957054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return oldest;
958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
965f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[portIndex].size(); i-- > 0;) {
967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, freeBuffer(portIndex, i));
968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDealer[portIndex].clear();
971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
975349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huberstatus_t ACodec::freeOutputBuffersNotOwnedByComponent() {
976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9802ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // At this time some buffers may still be with the component
9812ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // or being drained.
9822ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT &&
9832ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar            info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) {
984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK, freeBuffer(kPortIndexOutput, i));
985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
991f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(info->mStatus == BufferInfo::OWNED_BY_US
995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput && mNativeWindow != NULL
998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && info->mStatus == BufferInfo::OWNED_BY_US) {
9993fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        cancelBufferToNativeWindow(info);
1000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(mOMX->freeBuffer(
1003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, portIndex, info->mBufferID),
1004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
1005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mBuffers[portIndex].removeAt(i);
1007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1011f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::findBufferByID(
1012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        uint32_t portIndex, IOMX::buffer_id bufferID,
1013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ssize_t *index) {
1014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
1015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
1016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mBufferID == bufferID) {
1018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (index != NULL) {
1019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                *index = i;
1020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
1022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
1026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
1028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10305778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setComponentRole(
1031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        bool isEncoder, const char *mime) {
1032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    struct MimeToRole {
1033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime;
1034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *decoderRole;
1035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *encoderRole;
1036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
1037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const MimeToRole kMimeToRole[] = {
1039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG,
1040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.mp3", "audio_encoder.mp3" },
10412944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
10422944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp1", "audio_encoder.mp1" },
10432944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
10442944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp2", "audio_encoder.mp2" },
1045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_NB,
1046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrnb", "audio_encoder.amrnb" },
1047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_WB,
1048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrwb", "audio_encoder.amrwb" },
1049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AAC,
1050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.aac", "audio_encoder.aac" },
1051729de186450f78c099637e1fce743fe531862c52Andreas Huber        { MEDIA_MIMETYPE_AUDIO_VORBIS,
1052729de186450f78c099637e1fce743fe531862c52Andreas Huber            "audio_decoder.vorbis", "audio_encoder.vorbis" },
1053bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian        { MEDIA_MIMETYPE_AUDIO_OPUS,
1054bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian            "audio_decoder.opus", "audio_encoder.opus" },
1055c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_MLAW,
1056c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" },
1057c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_ALAW,
1058c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711alaw", "audio_encoder.g711alaw" },
1059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_AVC,
1060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.avc", "video_encoder.avc" },
10612472b1c0d63454e5d90a982bd6c555de6c3127bdRachad        { MEDIA_MIMETYPE_VIDEO_HEVC,
10622472b1c0d63454e5d90a982bd6c555de6c3127bdRachad            "video_decoder.hevc", "video_encoder.hevc" },
1063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_MPEG4,
1064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.mpeg4", "video_encoder.mpeg4" },
1065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_H263,
1066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.h263", "video_encoder.h263" },
106794705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP8,
106894705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp8", "video_encoder.vp8" },
106994705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP9,
107094705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp9", "video_encoder.vp9" },
1071ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        { MEDIA_MIMETYPE_AUDIO_RAW,
1072ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            "audio_decoder.raw", "audio_encoder.raw" },
10732f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        { MEDIA_MIMETYPE_AUDIO_FLAC,
10742f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            "audio_decoder.flac", "audio_encoder.flac" },
1075ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        { MEDIA_MIMETYPE_AUDIO_MSGSM,
1076ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen            "audio_decoder.gsm", "audio_encoder.gsm" },
1077774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu        { MEDIA_MIMETYPE_VIDEO_MPEG2,
1078774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu            "video_decoder.mpeg2", "video_encoder.mpeg2" },
107997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        { MEDIA_MIMETYPE_AUDIO_AC3,
108097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            "audio_decoder.ac3", "audio_encoder.ac3" },
1081f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
1082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const size_t kNumMimeToRole =
1084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
1085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1086f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    size_t i;
1087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (i = 0; i < kNumMimeToRole; ++i) {
1088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcasecmp(mime, kMimeToRole[i].mime)) {
1089f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (i == kNumMimeToRole) {
10945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_UNSUPPORTED;
1095f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    const char *role =
1098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        isEncoder ? kMimeToRole[i].encoderRole
1099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                  : kMimeToRole[i].decoderRole;
1100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (role != NULL) {
1102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_PARAM_COMPONENTROLETYPE roleParams;
1103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        InitOMXParams(&roleParams);
1104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        strncpy((char *)roleParams.cRole,
1106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                role, OMX_MAX_STRINGNAME_SIZE - 1);
1107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
1109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->setParameter(
1111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamStandardComponentRole,
1112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &roleParams, sizeof(roleParams));
1113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
11155ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("[%s] Failed to set standard component role '%s'.",
1116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 mComponentName.c_str(), role);
11175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
1119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
11215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
1123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
11255778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::configureCodec(
1126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime, const sp<AMessage> &msg) {
11275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t encoder;
11285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("encoder", &encoder)) {
11295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        encoder = false;
11305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1132e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    sp<AMessage> inputFormat = new AMessage();
1133e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    sp<AMessage> outputFormat = new AMessage();
1134e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
11355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mIsEncoder = encoder;
1136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
11375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setComponentRole(encoder /* isEncoder */, mime);
11385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
11405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
11415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
11425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitRate = 0;
11442f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    // FLAC encoder doesn't need a bitrate, other encoders do
11452f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
11462f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            && !msg->findInt32("bitrate", &bitRate)) {
11475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
11485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
11495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1150d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    int32_t storeMeta;
1151d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (encoder
1152d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && msg->findInt32("store-metadata-in-buffers", &storeMeta)
1153d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && storeMeta != 0) {
1154d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE);
1155d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1156d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (err != OK) {
1157308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              ALOGE("[%s] storeMetaDataInBuffers (input) failed w/ err %d",
1158308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    mComponentName.c_str(), err);
1159d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1160308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              return err;
1161308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang          }
1162308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang      }
1163d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1164308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t prependSPSPPS = 0;
11653a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    if (encoder
11663a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
11673a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && prependSPSPPS != 0) {
11683a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        OMX_INDEXTYPE index;
11693a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        err = mOMX->getExtensionIndex(
11703a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                mNode,
11713a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                "OMX.google.android.index.prependSPSPPSToIDRFrames",
11723a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                &index);
11733a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
11743a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err == OK) {
11753a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            PrependSPSPPSToIDRFramesParams params;
11763a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            InitOMXParams(&params);
11773a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            params.bEnable = OMX_TRUE;
11783a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
11793a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            err = mOMX->setParameter(
11803a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                    mNode, index, &params, sizeof(params));
11813a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
11823a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
11833a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err != OK) {
11843a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            ALOGE("Encoder could not be configured to emit SPS/PPS before "
11853a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                  "IDR frames. (err %d)", err);
11863a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
11873a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            return err;
11883a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
11893a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    }
11903a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
1191308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // Only enable metadata mode on encoder output if encoder can prepend
1192308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // sps/pps to idr frames, since in metadata mode the bitstream is in an
1193308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // opaque handle, to which we don't have access.
1194308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t video = !strncasecmp(mime, "video/", 6);
1195308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (encoder && video) {
1196308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS
1197308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && msg->findInt32("store-metadata-in-buffers-output", &storeMeta)
1198308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && storeMeta != 0);
1199308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1200308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, enable);
1201308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1202308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        if (err != OK) {
1203308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            ALOGE("[%s] storeMetaDataInBuffers (output) failed w/ err %d",
1204308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                mComponentName.c_str(), err);
1205308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = 0;
1206308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        } else {
1207308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = enable;
1208308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        }
1209a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
1210a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (!msg->findInt64(
1211a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    "repeat-previous-frame-after",
1212a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    &mRepeatFrameDelayUs)) {
1213a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            mRepeatFrameDelayUs = -1ll;
1214a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
121594ee4b708acfa941581160b267afb79192b1d816Chong Zhang
121694ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (!msg->findInt64("max-pts-gap-to-encoder", &mMaxPtsGapUs)) {
12172c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mMaxPtsGapUs = -1ll;
12182c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
12192c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
12202c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (!msg->findInt64("time-lapse", &mTimePerCaptureUs)) {
12212c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mTimePerCaptureUs = -1ll;
122294ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
122372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
122472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (!msg->findInt32(
122572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    "create-input-buffers-suspended",
122672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    (int32_t*)&mCreateInputBuffersSuspended)) {
122772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mCreateInputBuffersSuspended = false;
122872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
1229308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    }
1230308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1231054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    sp<RefBase> obj;
1232054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    int32_t haveNativeWindow = msg->findObject("native-window", &obj) &&
12335a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        obj != NULL;
1234054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mStoreMetaDataInOutputBuffers = false;
1235e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if (video && !encoder) {
1236e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        inputFormat->setInt32("adaptive-playback", false);
1237e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
1238054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (!encoder && video && haveNativeWindow) {
12395a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        sp<NativeWindowWrapper> windowWrapper(
12405a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                static_cast<NativeWindowWrapper *>(obj.get()));
12415a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        sp<ANativeWindow> nativeWindow = windowWrapper->getNativeWindow();
12425a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
12435a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        int32_t tunneled;
12445a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        if (msg->findInt32("feature-tunneled-playback", &tunneled) &&
12455a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            tunneled != 0) {
12465a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            ALOGI("Configuring TUNNELED video playback.");
12475a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
124897827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad            int32_t audioHwSync = 0;
124997827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad            if (!msg->findInt32("audio-hw-sync", &audioHwSync)) {
12505a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGW("No Audio HW Sync provided for video tunnel");
12515a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            }
12525a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            err = configureTunneledVideoPlayback(audioHwSync, nativeWindow);
12535a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (err != OK) {
125497827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad                ALOGE("configureTunneledVideoPlayback(%d,%p) failed!",
12555a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        audioHwSync, nativeWindow.get());
12565a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                return err;
1257fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
1258fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
12595a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            inputFormat->setInt32("adaptive-playback", true);
12605a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        } else {
12615a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            // Always try to enable dynamic output buffers on native surface
12625a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            err = mOMX->storeMetaDataInBuffers(
12635a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    mNode, kPortIndexOutput, OMX_TRUE);
12645a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (err != OK) {
12655a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d",
1266fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        mComponentName.c_str(), err);
1267e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
12685a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // if adaptive playback has been requested, try JB fallback
12695a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // NOTE: THIS FALLBACK MECHANISM WILL BE REMOVED DUE TO ITS
12705a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // LARGE MEMORY REQUIREMENT
12715a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
12725a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // we will not do adaptive playback on software accessed
12735a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // surfaces as they never had to respond to changes in the
12745a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // crop window, and we don't trust that they will be able to.
12755a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                int usageBits = 0;
12765a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                bool canDoAdaptivePlayback;
12775a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
12785a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                if (nativeWindow->query(
12795a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        nativeWindow.get(),
12805a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        NATIVE_WINDOW_CONSUMER_USAGE_BITS,
12815a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        &usageBits) != OK) {
12825a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    canDoAdaptivePlayback = false;
12835a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                } else {
12845a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    canDoAdaptivePlayback =
12855a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        (usageBits &
12865a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                                (GRALLOC_USAGE_SW_READ_MASK |
12875a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                                 GRALLOC_USAGE_SW_WRITE_MASK)) == 0;
12885a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                }
12895a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
12905a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                int32_t maxWidth = 0, maxHeight = 0;
12915a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                if (canDoAdaptivePlayback &&
12925a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        msg->findInt32("max-width", &maxWidth) &&
12935a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        msg->findInt32("max-height", &maxHeight)) {
12945a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    ALOGV("[%s] prepareForAdaptivePlayback(%dx%d)",
12955a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mComponentName.c_str(), maxWidth, maxHeight);
12965a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
12975a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    err = mOMX->prepareForAdaptivePlayback(
12985a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mNode, kPortIndexOutput, OMX_TRUE, maxWidth,
12995a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            maxHeight);
13005a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    ALOGW_IF(err != OK,
13015a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            "[%s] prepareForAdaptivePlayback failed w/ err %d",
13025a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mComponentName.c_str(), err);
13035a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
13045a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    if (err == OK) {
13055a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("max-width", maxWidth);
13065a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("max-height", maxHeight);
13075a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("adaptive-playback", true);
13085a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    }
1309e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
13105a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // allow failure
13115a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                err = OK;
13125a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            } else {
13135a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGV("[%s] storeMetaDataInBuffers succeeded",
13145a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        mComponentName.c_str());
13155a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                mStoreMetaDataInOutputBuffers = true;
13165a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                inputFormat->setInt32("adaptive-playback", true);
1317fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
13180167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber
13195a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            int32_t push;
13205a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (msg->findInt32("push-blank-buffers-on-shutdown", &push)
13215a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    && push != 0) {
13225a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
13235a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            }
13240167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        }
1325e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang
1326e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        int32_t rotationDegrees;
1327e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        if (msg->findInt32("rotation-degrees", &rotationDegrees)) {
1328e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            mRotationDegrees = rotationDegrees;
1329e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        } else {
1330e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            mRotationDegrees = 0;
1331e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        }
1332054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1333054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1334308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (video) {
13355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (encoder) {
13365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupVideoEncoder(mime, msg);
13375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
133889869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            err = setupVideoDecoder(mime, msg);
13395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
134042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
134142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        int32_t numChannels, sampleRate;
134242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        if (!msg->findInt32("channel-count", &numChannels)
134342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
134442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // Since we did not always check for these, leave them optional
134542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // and have the decoder figure it all out.
134642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = OK;
134742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        } else {
134842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = setupRawAudioFormat(
134942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    encoder ? kPortIndexInput : kPortIndexOutput,
135042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    sampleRate,
135142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    numChannels);
135242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        }
1353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
1354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t numChannels, sampleRate;
13555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)
13565778822d86b0337407514b9372562b86edfa91cdAndreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
13575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
13585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
1359aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            int32_t isADTS, aacProfile;
1360b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            int32_t sbrMode;
13618045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            int32_t maxOutputChannelCount;
13628045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            drcParams_t drc;
1363ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            if (!msg->findInt32("is-adts", &isADTS)) {
1364ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                isADTS = 0;
1365ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
1366aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (!msg->findInt32("aac-profile", &aacProfile)) {
1367aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                aacProfile = OMX_AUDIO_AACObjectNull;
1368aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
1369b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            if (!msg->findInt32("aac-sbr-mode", &sbrMode)) {
1370b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                sbrMode = -1;
1371b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            }
1372ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
13738045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-max-output-channel_count", &maxOutputChannelCount)) {
13748045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                maxOutputChannelCount = -1;
13758045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
13768045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-encoded-target-level", &drc.encodedTargetLevel)) {
13778045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
13788045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.encodedTargetLevel = -1;
13798045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
13808045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-cut-level", &drc.drcCut)) {
13818045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
13828045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.drcCut = -1;
13838045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
13848045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-boost-level", &drc.drcBoost)) {
13858045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
13868045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.drcBoost = -1;
13878045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
13888045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-heavy-compression", &drc.heavyCompression)) {
13898045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
13908045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.heavyCompression = -1;
13918045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
13928045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-target-ref-level", &drc.targetRefLevel)) {
13938045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
13948045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.targetRefLevel = -1;
13958045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
13968045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi
1397ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            err = setupAACCodec(
13984471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    encoder, numChannels, sampleRate, bitRate, aacProfile,
13998045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                    isADTS != 0, sbrMode, maxOutputChannelCount, drc);
14005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
1401729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
14025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
1403729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
14045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
1405729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
1406729de186450f78c099637e1fce743fe531862c52Andreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
1407729de186450f78c099637e1fce743fe531862c52Andreas Huber        // These are PCM-like formats with a fixed sample rate but
1408729de186450f78c099637e1fce743fe531862c52Andreas Huber        // a variable number of channels.
1409729de186450f78c099637e1fce743fe531862c52Andreas Huber
1410729de186450f78c099637e1fce743fe531862c52Andreas Huber        int32_t numChannels;
14115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)) {
14125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
14135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
14145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupG711Codec(encoder, numChannels);
14155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14162f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
14172f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        int32_t numChannels, sampleRate, compressionLevel = -1;
14182f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (encoder &&
14192f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                (!msg->findInt32("channel-count", &numChannels)
14202f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                        || !msg->findInt32("sample-rate", &sampleRate))) {
14212f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("missing channel count or sample rate for FLAC encoder");
14222f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            err = INVALID_OPERATION;
14232f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        } else {
14242f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            if (encoder) {
1425516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                if (!msg->findInt32(
1426cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                            "complexity", &compressionLevel) &&
1427cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                    !msg->findInt32(
1428516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                            "flac-compression-level", &compressionLevel)) {
1429cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                    compressionLevel = 5; // default FLAC compression level
14302f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel < 0) {
1431516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1432516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 0",
1433516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
14342f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 0;
14352f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel > 8) {
1436516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1437516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 8",
1438516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
14392f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 8;
14402f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                }
14412f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            }
1442516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            err = setupFlacCodec(
1443516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    encoder, numChannels, sampleRate, compressionLevel);
14442f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
1445ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
1446ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        int32_t numChannels, sampleRate;
1447ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        if (encoder
1448ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("channel-count", &numChannels)
1449ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
1450ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = INVALID_OPERATION;
1451ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        } else {
1452ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
1453ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        }
145497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AC3)) {
145597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t numChannels;
145697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t sampleRate;
145797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        if (!msg->findInt32("channel-count", &numChannels)
145897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                || !msg->findInt32("sample-rate", &sampleRate)) {
145997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = INVALID_OPERATION;
146097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        } else {
146197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = setupAC3Codec(encoder, numChannels, sampleRate);
146297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        }
14635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1464729de186450f78c099637e1fce743fe531862c52Andreas Huber
14654471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    if (err != OK) {
14664471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber        return err;
14674471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    }
14684471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber
14698b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
14708b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderDelay = 0;
14718b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
14729806555d3930be43e11106281dee354820ac1c88Andreas Huber
14738b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
14748b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderPadding = 0;
14758b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
14768b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen
14779806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (msg->findInt32("channel-mask", &mChannelMask)) {
14789806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = true;
14799806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else {
14809806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = false;
14819806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
14829806555d3930be43e11106281dee354820ac1c88Andreas Huber
1483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t maxInputSize;
1484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (msg->findInt32("max-input-size", &maxInputSize)) {
14855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
1486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
14875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
1488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
14895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1490e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ(getPortFormat(kPortIndexInput, inputFormat), (status_t)OK);
1491e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ(getPortFormat(kPortIndexOutput, outputFormat), (status_t)OK);
1492e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mInputFormat = inputFormat;
1493e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mOutputFormat = outputFormat;
1494e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
14955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
1496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1498f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
1499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
1501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
1502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (def.nBufferSize >= size) {
1511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
1512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nBufferSize = size;
1515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
1517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->getParameter(
1524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(def.nBufferSize >= size);
1531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
15355778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::selectAudioPortFormat(
15365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
15375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_AUDIO_PARAM_PORTFORMATTYPE format;
15385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&format);
15395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    format.nPortIndex = portIndex;
15415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (OMX_U32 index = 0;; ++index) {
15425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        format.nIndex = index;
15435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
15455778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioPortFormat,
15465778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &format, sizeof(format));
15475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
15495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
15505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (format.eEncoding == desiredFormat) {
15535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
15545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
15585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format));
15595778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
15605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15615778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAACCodec(
1562aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        bool encoder, int32_t numChannels, int32_t sampleRate,
15638045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        int32_t bitRate, int32_t aacProfile, bool isADTS, int32_t sbrMode,
15648045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        int32_t maxOutputChannelCount, const drcParams_t& drc) {
1565ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (encoder && isADTS) {
1566ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return -EINVAL;
1567ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
1568ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
15695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setupRawAudioFormat(
15705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
15715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sampleRate,
15725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            numChannels);
15735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
15755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
15765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (encoder) {
15795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
15805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
15825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
15835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
15865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
15875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = kPortIndexOutput;
15885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
15905778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
15915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
15935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
15945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.bFlagErrorConcealment = OMX_TRUE;
15975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
15985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
16005778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
16015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
16035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
16045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
16075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&profile);
16085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nPortIndex = kPortIndexOutput;
16095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
16115778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
16125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
16145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
16155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nChannels = numChannels;
16185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eChannelMode =
16205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (numChannels == 1)
16215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
16225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nSampleRate = sampleRate;
16245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nBitRate = bitRate;
16255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAudioBandWidth = 0;
16265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nFrameLength = 0;
16275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACtools = OMX_AUDIO_AACToolAll;
16285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACERtools = OMX_AUDIO_AACERNone;
1629aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
16305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
1631b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        switch (sbrMode) {
1632b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 0:
1633b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // disable sbr
1634b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
1635b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
1636b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
1637b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 1:
1638b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable single-rate sbr
1639b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
1640b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
1641b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
1642b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 2:
1643b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable dual-rate sbr
1644b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
1645b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
1646b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
1647b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case -1:
1648b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable both modes -> the codec will decide which mode should be used
1649b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
1650b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
1651b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
1652b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        default:
1653b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // unsupported sbr mode
1654b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            return BAD_VALUE;
1655b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        }
1656b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi
16575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
16595778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
16605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
16625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
16635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
16665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_AUDIO_PARAM_AACPROFILETYPE profile;
1669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&profile);
1670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nPortIndex = kPortIndexInput;
1671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
16725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
1673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
1674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nChannels = numChannels;
1680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nSampleRate = sampleRate;
1681ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1682ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    profile.eAACStreamFormat =
1683ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        isADTS
1684ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            ? OMX_AUDIO_AACStreamFormatMP4ADTS
1685ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            : OMX_AUDIO_AACStreamFormatMP4FF;
1686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
16878045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    OMX_AUDIO_PARAM_ANDROID_AACPRESENTATIONTYPE presentation;
16888045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nMaxOutputChannels = maxOutputChannelCount;
16898045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nDrcCut = drc.drcCut;
16908045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nDrcBoost = drc.drcBoost;
16918045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nHeavyCompression = drc.heavyCompression;
16928045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nTargetReferenceLevel = drc.targetRefLevel;
16938045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nEncodedTargetLevel = drc.encodedTargetLevel;
16948045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi
16958045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    status_t res = mOMX->setParameter(mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
16968045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    if (res == OK) {
16978045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        // optional parameters, will not cause configuration failure
16988045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        mOMX->setParameter(mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAacPresentation,
16998045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                &presentation, sizeof(presentation));
17008045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    } else {
17018045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        ALOGW("did not set AudioAndroidAacPresentation due to error %d when setting AudioAac", res);
17028045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    }
17038045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    return res;
17045778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
170697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryustatus_t ACodec::setupAC3Codec(
170797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        bool encoder, int32_t numChannels, int32_t sampleRate) {
170897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    status_t err = setupRawAudioFormat(
170997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
171097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
171197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
171297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
171397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
171497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
171597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (encoder) {
171697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        ALOGW("AC3 encoding is not supported.");
171797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return INVALID_OPERATION;
171897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
171997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
172097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    OMX_AUDIO_PARAM_ANDROID_AC3TYPE def;
172197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    InitOMXParams(&def);
172297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nPortIndex = kPortIndexInput;
172397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
172497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    err = mOMX->getParameter(
172597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
172697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
172797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
172897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
172997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
173097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
173197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
173297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
173397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
173497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nChannels = numChannels;
173597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nSampleRate = sampleRate;
173697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
173797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    return mOMX->setParameter(
173897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
173997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
174097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
174197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
174297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu}
174397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
17445778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
17455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        bool isAMRWB, int32_t bps) {
17465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (isAMRWB) {
17475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 6600) {
17485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB0;
17495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 8850) {
17505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB1;
17515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 12650) {
17525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB2;
17535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 14250) {
17545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB3;
17555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 15850) {
17565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB4;
17575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 18250) {
17585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB5;
17595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 19850) {
17605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB6;
17615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 23050) {
17625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB7;
17635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 23850 bps
17665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeWB8;
17675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {  // AMRNB
17685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 4750) {
17695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB0;
17705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5150) {
17715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB1;
17725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5900) {
17735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB2;
17745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 6700) {
17755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB3;
17765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7400) {
17775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB4;
17785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7950) {
17795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB5;
17805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 10200) {
17815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB6;
17825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 12200 bps
17855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeNB7;
17865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
17895778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
1790729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_AMRTYPE def;
1791729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
17925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
1793729de186450f78c099637e1fce743fe531862c52Andreas Huber
1794729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err =
1795729de186450f78c099637e1fce743fe531862c52Andreas Huber        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1796729de186450f78c099637e1fce743fe531862c52Andreas Huber
1797729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1798729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1799729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1800729de186450f78c099637e1fce743fe531862c52Andreas Huber
1801729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
18025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
18035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
18055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1806729de186450f78c099637e1fce743fe531862c52Andreas Huber
18075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1810729de186450f78c099637e1fce743fe531862c52Andreas Huber
18115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupRawAudioFormat(
18125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
18135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            isWAMR ? 16000 : 8000 /* sampleRate */,
18145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            1 /* numChannels */);
1815729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1816729de186450f78c099637e1fce743fe531862c52Andreas Huber
18175778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupG711Codec(bool encoder, int32_t numChannels) {
18185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(!encoder);  // XXX TODO
18195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1820729de186450f78c099637e1fce743fe531862c52Andreas Huber    return setupRawAudioFormat(
1821729de186450f78c099637e1fce743fe531862c52Andreas Huber            kPortIndexInput, 8000 /* sampleRate */, numChannels);
1822729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1823729de186450f78c099637e1fce743fe531862c52Andreas Huber
18242f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivistatus_t ACodec::setupFlacCodec(
18252f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
18262f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
18272f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder) {
18282f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        OMX_AUDIO_PARAM_FLACTYPE def;
18292f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        InitOMXParams(&def);
18302f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nPortIndex = kPortIndexOutput;
18312f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
18322f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        // configure compression level
18332f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        status_t err = mOMX->getParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
18342f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
18352f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
18362f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
18372f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
18382f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nCompressionLevel = compressionLevel;
18392f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        err = mOMX->setParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
18402f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
18412f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
18422f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
18432f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
18442f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
18452f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
18462f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    return setupRawAudioFormat(
18472f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            encoder ? kPortIndexInput : kPortIndexOutput,
18482f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            sampleRate,
18492f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            numChannels);
18502f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi}
18512f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
1852729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t ACodec::setupRawAudioFormat(
1853729de186450f78c099637e1fce743fe531862c52Andreas Huber        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
1854729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1855729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
1856729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.nPortIndex = portIndex;
1857729de186450f78c099637e1fce743fe531862c52Andreas Huber
1858729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err = mOMX->getParameter(
1859729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1860729de186450f78c099637e1fce743fe531862c52Andreas Huber
1861729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1862729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1863729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1864729de186450f78c099637e1fce743fe531862c52Andreas Huber
1865729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
1866729de186450f78c099637e1fce743fe531862c52Andreas Huber
1867729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->setParameter(
1868729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1869729de186450f78c099637e1fce743fe531862c52Andreas Huber
1870729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1871729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1872729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1873729de186450f78c099637e1fce743fe531862c52Andreas Huber
1874729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
1875729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&pcmParams);
1876729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nPortIndex = portIndex;
1877729de186450f78c099637e1fce743fe531862c52Andreas Huber
1878729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->getParameter(
1879729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1880729de186450f78c099637e1fce743fe531862c52Andreas Huber
1881729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1882729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1883729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1884729de186450f78c099637e1fce743fe531862c52Andreas Huber
1885729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nChannels = numChannels;
1886729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.eNumData = OMX_NumericalDataSigned;
1887729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.bInterleaved = OMX_TRUE;
1888729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nBitPerSample = 16;
1889729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nSamplingRate = sampleRate;
1890729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
1891729de186450f78c099637e1fce743fe531862c52Andreas Huber
1892c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber    if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
1893c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber        return OMX_ErrorNone;
1894729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1895729de186450f78c099637e1fce743fe531862c52Andreas Huber
1896729de186450f78c099637e1fce743fe531862c52Andreas Huber    return mOMX->setParameter(
1897729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1898729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1899729de186450f78c099637e1fce743fe531862c52Andreas Huber
19005a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachadstatus_t ACodec::configureTunneledVideoPlayback(
190197827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad        int32_t audioHwSync, const sp<ANativeWindow> &nativeWindow) {
19025a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    native_handle_t* sidebandHandle;
19035a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
19045a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    status_t err = mOMX->configureVideoTunnelMode(
19055a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            mNode, kPortIndexOutput, OMX_TRUE, audioHwSync, &sidebandHandle);
19065a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    if (err != OK) {
19075a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        ALOGE("configureVideoTunnelMode failed! (err %d).", err);
19085a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        return err;
19095a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    }
19105a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
19115a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    err = native_window_set_sideband_stream(nativeWindow.get(), sidebandHandle);
19125a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    if (err != OK) {
19135a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        ALOGE("native_window_set_sideband_stream(%p) failed! (err %d).",
19145a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                sidebandHandle, err);
19155a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        return err;
19165a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    }
19175a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
19185a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    return OK;
19195a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad}
19205a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
1921f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoPortFormatType(
1922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
1923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_VIDEO_CODINGTYPE compressionFormat,
1924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_COLOR_FORMATTYPE colorFormat) {
1925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
1927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = portIndex;
1928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
1929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool found = false;
1930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 index = 0;
1932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (;;) {
1933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        format.nIndex = index;
1934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->getParameter(
1935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamVideoPortFormat,
1936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &format, sizeof(format));
1937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
1939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return err;
1940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1942229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        // substitute back flexible color format to codec supported format
1943229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        OMX_U32 flexibleEquivalent;
1944229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        if (compressionFormat == OMX_VIDEO_CodingUnused &&
1945229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                isFlexibleColorFormat(
1946229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                        mOMX, mNode, format.eColorFormat, &flexibleEquivalent) &&
1947229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                colorFormat == flexibleEquivalent) {
1948229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            ALOGI("[%s] using color format %#x in place of %#x",
1949229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                    mComponentName.c_str(), format.eColorFormat, colorFormat);
1950229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            colorFormat = format.eColorFormat;
1951229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
1952229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
1953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The following assertion is violated by TI's video decoder.
1954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // CHECK_EQ(format.nIndex, index);
1955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
1957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexInput
1958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && colorFormat == format.eColorFormat) {
1959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eCompressionFormat does not seem right.
1960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
1961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
1962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexOutput
1964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && compressionFormat == format.eCompressionFormat) {
1965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eColorFormat does not seem right.
1966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
1967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
1968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (format.eCompressionFormat == compressionFormat
1972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && format.eColorFormat == colorFormat) {
1973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            found = true;
1974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ++index;
1978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!found) {
1981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return UNKNOWN_ERROR;
1982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->setParameter(
1985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
1989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1991f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setSupportedOutputFormat() {
1992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
1994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = kPortIndexOutput;
1995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
1996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
2000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
2001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)format.eCompressionFormat, (int)OMX_VIDEO_CodingUnused);
2002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mOMX->setParameter(
2004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
2005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
2006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2008e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic const struct VideoCodingMapEntry {
2009e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    const char *mMime;
2010e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    OMX_VIDEO_CODINGTYPE mVideoCodingType;
2011e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber} kVideoCodingMapEntry[] = {
2012e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC },
20132472b1c0d63454e5d90a982bd6c555de6c3127bdRachad    { MEDIA_MIMETYPE_VIDEO_HEVC, OMX_VIDEO_CodingHEVC },
2014e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 },
2015e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 },
2016e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 },
201794705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 },
201894705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 },
2019e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber};
2020e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
20215778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic status_t GetVideoCodingTypeFromMime(
20225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
2023e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
2024e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
2025e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
2026e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) {
2027e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *codingType = kVideoCodingMapEntry[i].mVideoCodingType;
2028e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
2029e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
2030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2032e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    *codingType = OMX_VIDEO_CodingUnused;
2033e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2034e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
2035e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
2036e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2037e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic status_t GetMimeTypeForVideoCoding(
2038e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        OMX_VIDEO_CODINGTYPE codingType, AString *mime) {
2039e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
2040e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
2041e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
2042e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) {
2043e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *mime = kVideoCodingMapEntry[i].mMime;
2044e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
2045e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
2046e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
2047e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2048e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    mime->clear();
2049e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2050e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
20515778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
20525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20535778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoDecoder(
205489869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        const char *mime, const sp<AMessage> &msg) {
205589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    int32_t width, height;
205689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    if (!msg->findInt32("width", &width)
205789869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            || !msg->findInt32("height", &height)) {
205889869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        return INVALID_OPERATION;
205989869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    }
206089869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar
20615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
20625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
20635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
2069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
2070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
207589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    int32_t tmp;
207689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    if (msg->findInt32("color-format", &tmp)) {
207789869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        OMX_COLOR_FORMATTYPE colorFormat =
207889869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            static_cast<OMX_COLOR_FORMATTYPE>(tmp);
207989869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        err = setVideoPortFormatType(
208089869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar                kPortIndexOutput, OMX_VIDEO_CodingUnused, colorFormat);
208189869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        if (err != OK) {
208289869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            ALOGW("[%s] does not support color format %d",
208389869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar                  mComponentName.c_str(), colorFormat);
208489869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            err = setSupportedOutputFormat();
208589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        }
208689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    } else {
208789869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        err = setSupportedOutputFormat();
208889869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    }
2089f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2094f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
2095f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, width, height, compressionFormat);
2096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
2102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
2103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
21115778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) {
21125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
21135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("color-format", &tmp)) {
21145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
21155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_COLOR_FORMATTYPE colorFormat =
21185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        static_cast<OMX_COLOR_FORMATTYPE>(tmp);
21195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setVideoPortFormatType(
21215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
21225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support color format %d",
21255778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str(), colorFormat);
21265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Input port configuration */
21315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
21335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&def);
21345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
21365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexInput;
21385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
21405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
21415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t width, height, bitrate;
21475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("width", &width)
21485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("height", &height)
21495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("bitrate", &bitrate)) {
21505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
21515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
21545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
21555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t stride;
21575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("stride", &stride)) {
21585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        stride = width;
21595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nStride = stride;
21625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t sliceHeight;
21645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("slice-height", &sliceHeight)) {
21655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sliceHeight = height;
21665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nSliceHeight = sliceHeight;
21695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
21715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
21735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
21745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
21755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
21765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
21775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
21792c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        mTimePerFrameUs = (int64_t) (1000000.0f / frameRate);
21805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
21835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
21845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = colorFormat;
21855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
21875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
21885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set input port definition parameters.",
21915778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
21925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Output port configuration */
21975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
21995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
22005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
22065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
22075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support compression format %d",
22105778822d86b0337407514b9372562b86edfa91cdAndreas Huber             mComponentName.c_str(), compressionFormat);
22115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexOutput;
22165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
22185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
22195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
22255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
22265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = 0;
22275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nBitrate = bitrate;
22285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = compressionFormat;
22295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = OMX_COLOR_FormatUnused;
22305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
22325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
22335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set output port definition parameters.",
22365778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
22375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (compressionFormat) {
22425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingMPEG4:
22435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupMPEG4EncoderParameters(msg);
22445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
22455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingH263:
22475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupH263EncoderParameters(msg);
22485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
22495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingAVC:
22515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupAVCEncoderParameters(msg);
22525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
22535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2254c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        case OMX_VIDEO_CodingHEVC:
2255c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            err = setupHEVCEncoderParameters(msg);
2256c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            break;
2257c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
225889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP8:
225989b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP9:
226089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            err = setupVPXEncoderParameters(msg);
226189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            break;
226289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
22635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
22645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
22655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGI("setupVideoEncoder succeeded");
22685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
22705778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
22715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22720dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dongstatus_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) {
22730dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    OMX_VIDEO_PARAM_INTRAREFRESHTYPE params;
22740dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    InitOMXParams(&params);
22750dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.nPortIndex = kPortIndexOutput;
22760dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
22770dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode);
22780dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
22790dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic ||
22800dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
22810dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
22820dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) {
22830dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
22840dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
22850dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nCirMBs = mbs;
22860dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
22870dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
22880dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive ||
22890dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
22900dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
22910dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) {
22920dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
22930dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
22940dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirMBs = mbs;
22950dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
22960dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t ref;
22970dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) {
22980dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
22990dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
23000dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirRef = ref;
23010dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
23020dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
23030dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = mOMX->setParameter(
23040dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            mNode, OMX_IndexParamVideoIntraRefresh,
23050dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            &params, sizeof(params));
23060dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    return err;
23070dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong}
23080dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
23095778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
23105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (iFramesInterval < 0) {
23115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0xFFFFFFFF;
23125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (iFramesInterval == 0) {
23135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0;
23145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_U32 ret = frameRate * iFramesInterval;
23165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(ret > 1);
23175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return ret;
23185778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
23195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
232096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatic OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) {
232196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    int32_t tmp;
232296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    if (!msg->findInt32("bitrate-mode", &tmp)) {
232396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        return OMX_Video_ControlRateVariable;
232496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    }
232596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
232696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp);
232796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber}
232896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
23295778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
23305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
23315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
23325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
23335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
23345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
233696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
233796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
23385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
23395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
23405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
23415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
23425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
23435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
23455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
23485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&mpeg4type);
23495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPortIndex = kPortIndexOutput;
23505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
23525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
23535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
23555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
23565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nSliceHeaderSpacing = 0;
23595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bSVH = OMX_FALSE;
23605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bGov = OMX_FALSE;
23615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nAllowedPictureTypes =
23635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
23645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
23665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mpeg4type.nPFrames == 0) {
23675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
23685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nBFrames = 0;
23705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nIDCVLCThreshold = 0;
23715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bACPred = OMX_TRUE;
23725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nMaxPacketSize = 256;
23735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nTimeIncRes = 1000;
23745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nHeaderExtension = 0;
23755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bReversibleVLC = OMX_FALSE;
23765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
23785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
23795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
23805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
23815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
23825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
23855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
23875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
23885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
23915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
23925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
23955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
23965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
23985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
23995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
240196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
24025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
24045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
24055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
24085778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
24095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24105778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
24115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
24125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
24135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
24145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
24155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
241796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
241896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
24195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
24205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
24215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
24225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
24235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
24245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
24255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
24265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_H263TYPE h263type;
24295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h263type);
24305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPortIndex = kPortIndexOutput;
24315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
24335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
24345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
24365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
24375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nAllowedPictureTypes =
24405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
24415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
24435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h263type.nPFrames == 0) {
24445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
24455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nBFrames = 0;
24475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
24495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
24505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
24515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
24525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
24535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
24545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
24565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
24585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
24595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
24605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
24625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
24635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bPLUSPTYPEAllowed = OMX_FALSE;
24665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bForceRoundingTypeToZero = OMX_FALSE;
24675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPictureHeaderRepetition = 0;
24685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nGOBHeaderInterval = 0;
24695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
24715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
24725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
24745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
24755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
247796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
24785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
24805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
24815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
24845778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
24855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24865778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
24875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
24885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
24895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
24905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
24915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
249396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
249496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
24955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
24965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
24975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
24985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
24995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
25005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
25015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
25025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25040dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = OK;
25050dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    int32_t intraRefreshMode = 0;
25060dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) {
25070dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode);
25080dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (err != OK) {
25090dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
25100dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong                    err, intraRefreshMode);
25110dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return err;
25120dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
25130dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
25140dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
25155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_AVCTYPE h264type;
25165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h264type);
25175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nPortIndex = kPortIndexOutput;
25185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25190dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    err = mOMX->getParameter(
25205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
25215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
25235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
25245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nAllowedPictureTypes =
25275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
25285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
25305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
25315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
25325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
25335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
25345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
25355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
25375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
25395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
25405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
25415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
25435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
25445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // XXX
25477c25df82dfc8bbedb58608242f0d923a4594bb14James Dong    if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) {
25487c25df82dfc8bbedb58608242f0d923a4594bb14James Dong        ALOGW("Use baseline profile instead of %d for AVC recording",
25497c25df82dfc8bbedb58608242f0d923a4594bb14James Dong            h264type.eProfile);
25505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
25515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
25545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nSliceHeaderSpacing = 0;
25555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bUseHadamard = OMX_TRUE;
25565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefFrames = 1;
25575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nBFrames = 0;
25585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
25595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (h264type.nPFrames == 0) {
25605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
25615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
25625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx10ActiveMinus1 = 0;
25635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx11ActiveMinus1 = 0;
25645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bEntropyCodingCABAC = OMX_FALSE;
25655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bWeightedPPrediction = OMX_FALSE;
25665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bconstIpred = OMX_FALSE;
25675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirect8x8Inference = OMX_FALSE;
25685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirectSpatialTemporal = OMX_FALSE;
25695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nCabacInitIdc = 0;
25705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.nBFrames != 0) {
25735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
25745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableUEP = OMX_FALSE;
25775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableFMO = OMX_FALSE;
25785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableASO = OMX_FALSE;
25795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableRS = OMX_FALSE;
25805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bFrameMBsOnly = OMX_TRUE;
25815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bMBAFF = OMX_FALSE;
25825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
25835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
25855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
25865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
25885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
25895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
259196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return configureBitrate(bitrate, bitrateMode);
25925778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
25935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2594c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachadstatus_t ACodec::setupHEVCEncoderParameters(const sp<AMessage> &msg) {
2595c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    int32_t bitrate, iFrameInterval;
2596c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findInt32("bitrate", &bitrate)
2597c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
2598c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return INVALID_OPERATION;
2599c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2600c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2601c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
2602c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2603c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    float frameRate;
2604c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findFloat("frame-rate", &frameRate)) {
2605c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t tmp;
2606c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("frame-rate", &tmp)) {
2607c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
2608c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
2609c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        frameRate = (float)tmp;
2610c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2611c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2612c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_PARAM_HEVCTYPE hevcType;
2613c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    InitOMXParams(&hevcType);
2614c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    hevcType.nPortIndex = kPortIndexOutput;
2615c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2616c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    status_t err = OK;
2617c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    err = mOMX->getParameter(
2618c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
2619c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
2620c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
2621c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2622c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2623c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    int32_t profile;
2624c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (msg->findInt32("profile", &profile)) {
2625c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t level;
2626c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("level", &level)) {
2627c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
2628c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
2629c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2630c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        err = verifySupportForProfileAndLevel(profile, level);
2631c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (err != OK) {
2632c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return err;
2633c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
2634c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2635c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eProfile = static_cast<OMX_VIDEO_HEVCPROFILETYPE>(profile);
2636c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eLevel = static_cast<OMX_VIDEO_HEVCLEVELTYPE>(level);
2637c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2638c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2639c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    // TODO: Need OMX structure definition for setting iFrameInterval
2640c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2641c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    err = mOMX->setParameter(
2642c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
2643c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
2644c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
2645c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2646c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2647c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    return configureBitrate(bitrate, bitrateMode);
2648c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad}
2649c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
265089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huberstatus_t ACodec::setupVPXEncoderParameters(const sp<AMessage> &msg) {
265189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    int32_t bitrate;
26524154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    int32_t iFrameInterval = 0;
26534154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    size_t tsLayers = 0;
26544154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE pattern =
26554154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        OMX_VIDEO_VPXTemporalLayerPatternNone;
26564154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    static const uint32_t kVp8LayerRateAlloction
26574154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS]
26584154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS] = {
26594154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        {100, 100, 100},  // 1 layer
26604154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 60, 100, 100},  // 2 layers {60%, 40%}
26614154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 40,  60, 100},  // 3 layers {40%, 20%, 40%}
26624154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    };
266389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    if (!msg->findInt32("bitrate", &bitrate)) {
266489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        return INVALID_OPERATION;
266589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    }
26664154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    msg->findInt32("i-frame-interval", &iFrameInterval);
266789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
266889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
266989b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
26704154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    float frameRate;
26714154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (!msg->findFloat("frame-rate", &frameRate)) {
26724154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        int32_t tmp;
26734154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (!msg->findInt32("frame-rate", &tmp)) {
26744154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            return INVALID_OPERATION;
26754154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
26764154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        frameRate = (float)tmp;
26774154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
26784154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
26794154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    AString tsSchema;
26804154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (msg->findString("ts-schema", &tsSchema)) {
26814154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (tsSchema == "webrtc.vp8.1-layer") {
26824154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
26834154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 1;
26844154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else if (tsSchema == "webrtc.vp8.2-layer") {
26854154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
26864154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 2;
26874154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else if (tsSchema == "webrtc.vp8.3-layer") {
26884154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
26894154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 3;
26904154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else {
26914154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            ALOGW("Unsupported ts-schema [%s]", tsSchema.c_str());
26924154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
26934154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
26944154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
26954154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
26964154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    InitOMXParams(&vp8type);
26974154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    vp8type.nPortIndex = kPortIndexOutput;
26984154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    status_t err = mOMX->getParameter(
26994154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
27004154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            &vp8type, sizeof(vp8type));
27014154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
27024154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (err == OK) {
27034154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (iFrameInterval > 0) {
27044154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nKeyFrameInterval = setPFramesSpacing(iFrameInterval, frameRate);
27054154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
27064154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.eTemporalPattern = pattern;
27074154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.nTemporalLayerCount = tsLayers;
27084154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (tsLayers > 0) {
27094154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            for (size_t i = 0; i < OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS; i++) {
27104154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                vp8type.nTemporalLayerBitrateRatio[i] =
27114154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                    kVp8LayerRateAlloction[tsLayers - 1][i];
27124154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            }
27134154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
27144154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (bitrateMode == OMX_Video_ControlRateConstant) {
27154154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMinQuantizer = 2;
27164154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMaxQuantizer = 63;
27174154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
27184154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
27194154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        err = mOMX->setParameter(
27204154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
27214154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                &vp8type, sizeof(vp8type));
27224154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (err != OK) {
27234154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            ALOGW("Extended VP8 parameters set failed: %d", err);
27244154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
27254154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
27264154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
272789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    return configureBitrate(bitrate, bitrateMode);
272889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber}
272989b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
27305778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::verifySupportForProfileAndLevel(
27315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t profile, int32_t level) {
27325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
27335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&params);
27345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    params.nPortIndex = kPortIndexOutput;
27355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (params.nProfileIndex = 0;; ++params.nProfileIndex) {
27375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
27385778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode,
27395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                OMX_IndexParamVideoProfileLevelQuerySupported,
27405778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &params,
27415778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sizeof(params));
27425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
27445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
27455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
27465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
27485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
27495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (profile == supportedProfile && level <= supportedLevel) {
27515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OK;
27525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
27535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27545778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
27555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
275696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatus_t ACodec::configureBitrate(
275796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) {
27585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
27595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&bitrateType);
27605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
27615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
27635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
27645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
27655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
27675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
27685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
277096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    bitrateType.eControlRate = bitrateMode;
27715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nTargetBitrate = bitrate;
27725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
27745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
27755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
27765778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
27775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27785778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupErrorCorrectionParameters() {
27795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
27805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&errorCorrectionType);
27815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nPortIndex = kPortIndexOutput;
27825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
27845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
27855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
27865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
27885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OK;  // Optional feature. Ignore this failure
27895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableHEC = OMX_FALSE;
27925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableResync = OMX_TRUE;
27935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nResynchMarkerSpacing = 256;
27945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
27955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableRVLC = OMX_FALSE;
27965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
27985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
27995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
28005778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
28015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2802f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoFormatOnPort(
2803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
2804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat) {
2805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
2806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
2807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
2808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
2810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
2812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
2815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
2817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // XXX Need a (much) better heuristic to compute input buffer sizes.
2818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const size_t X = 64 * 1024;
2819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (def.nBufferSize < X) {
2820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.nBufferSize = X;
2821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
2825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameWidth = width;
2827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameHeight = height;
2828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
2830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eCompressionFormat = compressionFormat;
2831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eColorFormat = OMX_COLOR_FormatUnused;
2832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
2835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
2838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2840f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::initNativeWindow() {
2841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL) {
2842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
2843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
2846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2849d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Hubersize_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
2850d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    size_t n = 0;
2851d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2852d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2853d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        const BufferInfo &info = mBuffers[portIndex].itemAt(i);
2854d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2855d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
2856d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            ++n;
2857d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        }
2858d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    }
2859d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2860d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    return n;
2861d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber}
2862d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
28637e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubersize_t ACodec::countBuffersOwnedByNativeWindow() const {
28647e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    size_t n = 0;
28657e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
28667e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
28677e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
28687e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
28697e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
28707e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            ++n;
28717e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        }
28727e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
28737e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
28747e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    return n;
28757e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
28767e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
28777e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubervoid ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
28787e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (mNativeWindow == NULL) {
28797e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        return;
28807e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
28817e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
2882e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    while (countBuffersOwnedByNativeWindow() > mNumUndequeuedBuffers
28837e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            && dequeueBufferFromNativeWindow() != NULL) {
2884c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        // these buffers will be submitted as regular buffers; account for this
2885c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        if (mStoreMetaDataInOutputBuffers && mMetaDataBuffersToSubmit > 0) {
2886c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar            --mMetaDataBuffersToSubmit;
2887c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        }
28887e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
28897e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
28907e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
2891f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs(
2892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
2893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
2895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus != BufferInfo::OWNED_BY_US
2897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
2898609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGV("[%s] Buffer %u on port %u still has status %d",
2899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mComponentName.c_str(),
2900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info->mBufferID, portIndex, info->mStatus);
2901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
2902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2908f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs() {
2909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return allYourBuffersAreBelongToUs(kPortIndexInput)
2910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        && allYourBuffersAreBelongToUs(kPortIndexOutput);
2911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2913f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::deferMessage(const sp<AMessage> &msg) {
2914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool wasEmptyBefore = mDeferredQueue.empty();
2915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.push_back(msg);
2916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2918f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::processDeferredMessages() {
2919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> > queue = mDeferredQueue;
2920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.clear();
2921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> >::iterator it = queue.begin();
2923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while (it != queue.end()) {
2924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        onMessageReceived(*it++);
2925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
292803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar// static
2929229d242665c612fd97431d1e7ac004823b47f181Lajos Molnarbool ACodec::describeDefaultColorFormat(DescribeColorFormatParams &params) {
293003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    MediaImage &image = params.sMediaImage;
293103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    memset(&image, 0, sizeof(image));
293203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
293303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mType = MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
293403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mNumPlanes = 0;
293503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
293603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    const OMX_COLOR_FORMATTYPE fmt = params.eColorFormat;
293703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    // we need stride and slice-height to be non-zero
293803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    if (params.nStride == 0 || params.nSliceHeight == 0) {
293903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        ALOGW("cannot describe color format 0x%x = %d with stride=%u and sliceHeight=%u",
294003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                fmt, fmt, params.nStride, params.nSliceHeight);
2941229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return false;
294203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    }
294303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
294403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mWidth = params.nFrameWidth;
294503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mHeight = params.nFrameHeight;
294603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
294703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    // only supporting YUV420
294803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    if (fmt != OMX_COLOR_FormatYUV420Planar &&
294903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        fmt != OMX_COLOR_FormatYUV420PackedPlanar &&
295003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        fmt != OMX_COLOR_FormatYUV420SemiPlanar &&
295103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        fmt != OMX_COLOR_FormatYUV420PackedSemiPlanar) {
295203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        ALOGW("do not know color format 0x%x = %d", fmt, fmt);
2953229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return false;
295403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    }
295503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
295603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    // set-up YUV format
295703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mType = MediaImage::MEDIA_IMAGE_TYPE_YUV;
295803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mNumPlanes = 3;
295903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mBitDepth = 8;
296003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mOffset = 0;
296103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mColInc = 1;
296203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mRowInc = params.nStride;
296303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mHorizSubsampling = 1;
296403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mVertSubsampling = 1;
296503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
296603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    switch (fmt) {
296703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420Planar: // used for YV12
296803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420PackedPlanar:
296903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight;
297003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mColInc = 1;
297103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mRowInc = params.nStride / 2;
297203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mHorizSubsampling = 2;
297303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mVertSubsampling = 2;
297403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
297503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset
297603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    + (params.nStride * params.nSliceHeight / 4);
297703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mColInc = 1;
297803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mRowInc = params.nStride / 2;
297903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mHorizSubsampling = 2;
298003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mVertSubsampling = 2;
298103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            break;
298203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
298303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420SemiPlanar:
298403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            // FIXME: NV21 for sw-encoder, NV12 for decoder and hw-encoder
298503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420PackedSemiPlanar:
298603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            // NV12
298703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight;
298803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mColInc = 2;
298903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mRowInc = params.nStride;
299003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mHorizSubsampling = 2;
299103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mVertSubsampling = 2;
299203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
299303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset + 1;
299403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mColInc = 2;
299503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mRowInc = params.nStride;
299603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mHorizSubsampling = 2;
299703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mVertSubsampling = 2;
299803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            break;
299903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
300003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        default:
300103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            TRESPASS();
300203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    }
3003229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    return true;
3004229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar}
3005229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3006229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar// static
3007229d242665c612fd97431d1e7ac004823b47f181Lajos Molnarbool ACodec::describeColorFormat(
3008229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        const sp<IOMX> &omx, IOMX::node_id node,
3009229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        DescribeColorFormatParams &describeParams)
3010229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar{
3011229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    OMX_INDEXTYPE describeColorFormatIndex;
3012229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    if (omx->getExtensionIndex(
3013229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            node, "OMX.google.android.index.describeColorFormat",
3014229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            &describeColorFormatIndex) != OK ||
3015229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        omx->getParameter(
3016229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            node, describeColorFormatIndex,
3017229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            &describeParams, sizeof(describeParams)) != OK) {
3018229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return describeDefaultColorFormat(describeParams);
3019229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    }
3020229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    return describeParams.sMediaImage.mType !=
3021229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
3022229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar}
3023229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3024229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar// static
3025229d242665c612fd97431d1e7ac004823b47f181Lajos Molnarbool ACodec::isFlexibleColorFormat(
3026229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar         const sp<IOMX> &omx, IOMX::node_id node,
3027229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar         uint32_t colorFormat, OMX_U32 *flexibleEquivalent) {
3028229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    DescribeColorFormatParams describeParams;
3029229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    InitOMXParams(&describeParams);
3030229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.eColorFormat = (OMX_COLOR_FORMATTYPE)colorFormat;
3031229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    // reasonable dummy values
3032229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nFrameWidth = 128;
3033229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nFrameHeight = 128;
3034229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nStride = 128;
3035229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nSliceHeight = 128;
3036229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3037229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    CHECK(flexibleEquivalent != NULL);
3038229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3039229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    if (!describeColorFormat(omx, node, describeParams)) {
3040229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return false;
3041229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    }
3042229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3043229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    const MediaImage &img = describeParams.sMediaImage;
3044229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    if (img.mType == MediaImage::MEDIA_IMAGE_TYPE_YUV) {
3045229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        if (img.mNumPlanes != 3 ||
3046229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            img.mPlane[img.Y].mHorizSubsampling != 1 ||
3047229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            img.mPlane[img.Y].mVertSubsampling != 1) {
3048229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            return false;
3049229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
3050229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3051229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        // YUV 420
3052229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        if (img.mPlane[img.U].mHorizSubsampling == 2
3053229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.U].mVertSubsampling == 2
3054229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.V].mHorizSubsampling == 2
3055229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.V].mVertSubsampling == 2) {
3056229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            // possible flexible YUV420 format
3057229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            if (img.mBitDepth <= 8) {
3058229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar               *flexibleEquivalent = OMX_COLOR_FormatYUV420Flexible;
3059229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar               return true;
3060229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            }
3061229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
3062229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    }
3063229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    return false;
306403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar}
306503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
3066e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarstatus_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> &notify) {
3067e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    // TODO: catch errors an return them instead of using CHECK
306831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
306931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    InitOMXParams(&def);
3070e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    def.nPortIndex = portIndex;
307131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
307231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ(mOMX->getParameter(
307331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)),
307431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber             (status_t)OK);
307531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3076e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ((int)def.eDir,
3077e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            (int)(portIndex == kPortIndexOutput ? OMX_DirOutput : OMX_DirInput));
307831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
307931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    switch (def.eDomain) {
308031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainVideo:
308131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
308231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
3083e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            switch ((int)videoDef->eCompressionFormat) {
3084e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_VIDEO_CodingUnused:
3085e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3086e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(mIsEncoder ^ (portIndex == kPortIndexOutput));
3087e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
3088e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3089e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("stride", videoDef->nStride);
3090e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("slice-height", videoDef->nSliceHeight);
3091e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("color-format", videoDef->eColorFormat);
3092e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
309303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    DescribeColorFormatParams describeParams;
309403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    InitOMXParams(&describeParams);
309503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    describeParams.eColorFormat = videoDef->eColorFormat;
309603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    describeParams.nFrameWidth = videoDef->nFrameWidth;
309703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    describeParams.nFrameHeight = videoDef->nFrameHeight;
309803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    describeParams.nStride = videoDef->nStride;
309903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    describeParams.nSliceHeight = videoDef->nSliceHeight;
310003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
3101229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                    if (describeColorFormat(mOMX, mNode, describeParams)) {
310203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                        notify->setBuffer(
310303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                                "image-data",
310403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                                ABuffer::CreateAsCopy(
310503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                                        &describeParams.sMediaImage,
310603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                                        sizeof(describeParams.sMediaImage)));
310703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    }
310803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
3109e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_CONFIG_RECTTYPE rect;
3110e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&rect);
3111e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    rect.nPortIndex = kPortIndexOutput;
3112e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3113e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    if (mOMX->getConfig(
3114e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                mNode, OMX_IndexConfigCommonOutputCrop,
3115e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &rect, sizeof(rect)) != OK) {
3116e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nLeft = 0;
3117e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nTop = 0;
3118e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nWidth = videoDef->nFrameWidth;
3119e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nHeight = videoDef->nFrameHeight;
3120e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    }
312131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3122e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nLeft, 0);
3123e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nTop, 0);
3124e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nWidth, 0u);
3125e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nHeight, 0u);
3126e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_LE(rect.nLeft + rect.nWidth - 1, videoDef->nFrameWidth);
3127e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_LE(rect.nTop + rect.nHeight - 1, videoDef->nFrameHeight);
3128e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3129e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setRect(
3130577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            "crop",
3131577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nLeft,
3132577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nTop,
3133e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                            rect.nLeft + rect.nWidth - 1,
3134e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                            rect.nTop + rect.nHeight - 1);
3135e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3136e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3137e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
31384730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
31394730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP8:
31404730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP9:
31414730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                {
31424730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
31434730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    InitOMXParams(&vp8type);
31444730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    vp8type.nPortIndex = kPortIndexOutput;
31454730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    status_t err = mOMX->getParameter(
31464730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            mNode,
31474730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
31484730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            &vp8type,
31494730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            sizeof(vp8type));
31504730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
31514730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    if (err == OK) {
31524730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        AString tsSchema = "none";
31534730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        if (vp8type.eTemporalPattern
31544730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                == OMX_VIDEO_VPXTemporalLayerPatternWebRTC) {
31554730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            switch (vp8type.nTemporalLayerCount) {
31564730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 1:
31574730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
31584730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.1-layer";
31594730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
31604730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
31614730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 2:
31624730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
31634730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.2-layer";
31644730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
31654730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
31664730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 3:
31674730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
31684730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.3-layer";
31694730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
31704730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
31714730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                default:
31724730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
31734730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
31744730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
31754730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            }
31764730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        }
31774730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        notify->setString("ts-schema", tsSchema);
31784730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    }
31794730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    // Fall through to set up mime.
31804730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                }
31814730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
3182e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                default:
3183e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3184e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(mIsEncoder ^ (portIndex == kPortIndexInput));
3185e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    AString mime;
3186e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    if (GetMimeTypeForVideoCoding(
3187e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        videoDef->eCompressionFormat, &mime) != OK) {
3188e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", "application/octet-stream");
3189e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    } else {
3190e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", mime.c_str());
3191e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    }
3192e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3193e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
319431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            }
3195e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3196e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("width", videoDef->nFrameWidth);
3197e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("height", videoDef->nFrameHeight);
319831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
319931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
320031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
320131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainAudio:
320231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
320331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
320431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
320597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            switch ((int)audioDef->eEncoding) {
3206e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingPCM:
3207e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3208e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_PCMMODETYPE params;
3209e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3210e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3211e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3212e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3213e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioPcm,
3214e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3215e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3216e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
321714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_GT(params.nChannels, 0);
3218e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK(params.nChannels == 1 || params.bInterleaved);
3219e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(params.nBitPerSample, 16u);
322014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
322114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.eNumData,
322214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_NumericalDataSigned);
322314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
322414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.ePCMMode,
322514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_AUDIO_PCMModeLinear);
3226e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3227e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
3228e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
3229e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSamplingRate);
3230e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3231e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mChannelMaskPresent) {
3232e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("channel-mask", mChannelMask);
32338b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                    }
3234e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
32358b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                }
32369806555d3930be43e11106281dee354820ac1c88Andreas Huber
3237e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAAC:
3238e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3239e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AACPROFILETYPE params;
3240e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3241e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3242e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3243e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3244e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAac,
3245e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3246e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3247e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3248e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
3249e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
3250e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
3251e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
3252e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
3253e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3254e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAMR:
3255e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3256e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AMRTYPE params;
3257e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3258e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
32599806555d3930be43e11106281dee354820ac1c88Andreas Huber
3260e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3261e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAmr,
3262e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3263e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3264e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3265e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", 1);
3266e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) {
3267e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
3268e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_WB);
3269e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3270e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 16000);
3271e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    } else {
3272e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
3273e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
3274e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3275e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 8000);
3276e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
3277e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
3278e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
3279e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3280e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingFLAC:
3281e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3282e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_FLACTYPE params;
3283e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3284e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3285e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3286e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3287e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioFlac,
3288e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3289e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3290e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3291e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC);
3292e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
3293e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
3294e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
3295e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
3296e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3297e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingMP3:
3298e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3299e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_MP3TYPE params;
3300e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
3301e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3302e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3303e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_EQ(mOMX->getParameter(
3304e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                mNode, OMX_IndexParamAudioMp3,
3305e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &params, sizeof(params)),
3306e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                             (status_t)OK);
3307e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3308e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MPEG);
3309e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
3310e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
3311e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3312e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
3313e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3314e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingVORBIS:
3315e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3316e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_VORBISTYPE params;
3317e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
3318e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3319e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3320e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_EQ(mOMX->getParameter(
3321e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                mNode, OMX_IndexParamAudioVorbis,
3322e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &params, sizeof(params)),
3323e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                             (status_t)OK);
3324e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3325e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_VORBIS);
3326e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
3327e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
3328e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3329e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
3330e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
333197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                case OMX_AUDIO_CodingAndroidAC3:
333297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                {
333397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    OMX_AUDIO_PARAM_ANDROID_AC3TYPE params;
333497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    InitOMXParams(&params);
3335e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
333697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
333797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    CHECK_EQ((status_t)OK, mOMX->getParameter(
333897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            mNode,
333997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
334097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            &params,
334197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            sizeof(params)));
334297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
334397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AC3);
334497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("channel-count", params.nChannels);
334597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("sample-rate", params.nSampleRate);
334697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    break;
334797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                }
3348e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
33498c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                case OMX_AUDIO_CodingAndroidOPUS:
33508c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                {
33518c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    OMX_AUDIO_PARAM_ANDROID_OPUSTYPE params;
33528c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    InitOMXParams(&params);
33538c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    params.nPortIndex = portIndex;
33548c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
33558c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    CHECK_EQ((status_t)OK, mOMX->getParameter(
33568c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            mNode,
33578c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus,
33588c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            &params,
33598c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            sizeof(params)));
33608c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
33618c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_OPUS);
33628c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("channel-count", params.nChannels);
33638c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("sample-rate", params.nSampleRate);
33648c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    break;
33658c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                }
33668c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
3367e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                default:
3368e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    ALOGE("UNKNOWN AUDIO CODING: %d\n", audioDef->eEncoding);
3369e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    TRESPASS();
3370e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
337131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
337231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
337331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
337431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        default:
337531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            TRESPASS();
337631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    }
337731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3378e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    return OK;
3379e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar}
3380e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3381e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarvoid ACodec::sendFormatChange(const sp<AMessage> &reply) {
3382e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    sp<AMessage> notify = mNotify->dup();
3383e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    notify->setInt32("what", kWhatOutputFormatChanged);
3384e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3385e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ(getPortFormat(kPortIndexOutput, notify), (status_t)OK);
3386e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3387e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    AString mime;
3388e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK(notify->findString("mime", &mime));
3389e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3390e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    int32_t left, top, right, bottom;
3391e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if (mime == MEDIA_MIMETYPE_VIDEO_RAW &&
3392e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        mNativeWindow != NULL &&
3393e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->findRect("crop", &left, &top, &right, &bottom)) {
3394e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        // notify renderer of the crop change
3395e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        // NOTE: native window uses extended right-bottom coordinate
3396e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        reply->setRect("crop", left, top, right + 1, bottom + 1);
3397e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    } else if (mime == MEDIA_MIMETYPE_AUDIO_RAW &&
3398e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar               (mEncoderDelay || mEncoderPadding)) {
3399e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        int32_t channelCount;
3400e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        CHECK(notify->findInt32("channel-count", &channelCount));
3401e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        size_t frameSize = channelCount * sizeof(int16_t);
3402e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        if (mSkipCutBuffer != NULL) {
3403e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            size_t prevbufsize = mSkipCutBuffer->size();
3404e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            if (prevbufsize != 0) {
3405e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                ALOGW("Replacing SkipCutBuffer holding %d "
3406e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                      "bytes",
3407e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                      prevbufsize);
3408e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            }
3409e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        }
3410e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        mSkipCutBuffer = new SkipCutBuffer(
3411e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                mEncoderDelay * frameSize,
3412e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                mEncoderPadding * frameSize);
3413e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
3414e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
341531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->post();
341631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
341731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mSentFormat = true;
341831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber}
341931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
34205778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
3421cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    sp<AMessage> notify = mNotify->dup();
3422d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatError);
3423251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    ALOGE("signalError(omxError %#x, internalError %d)", error, internalError);
3424251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
3425251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (internalError == UNKNOWN_ERROR) { // find better error code
3426251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        const status_t omxStatus = statusFromOMXError(error);
3427251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        if (omxStatus != 0) {
3428251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            internalError = omxStatus;
3429251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        } else {
3430251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            ALOGW("Invalid OMX error %#x", error);
3431251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        }
3432251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
34335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("err", internalError);
3434251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    notify->setInt32("actionCode", ACTION_CODE_FATAL); // could translate from OMX error.
3435cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->post();
3436cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber}
3437cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber
3438bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huberstatus_t ACodec::pushBlankBuffersToNativeWindow() {
3439bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    status_t err = NO_ERROR;
3440bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    ANativeWindowBuffer* anb = NULL;
3441bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int numBufs = 0;
3442bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int minUndequeuedBufs = 0;
3443bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3444bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We need to reconnect to the ANativeWindow as a CPU client to ensure that
3445bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // no frames get dropped by SurfaceFlinger assuming that these are video
3446bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // frames.
3447bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_disconnect(mNativeWindow.get(),
3448bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_MEDIA);
3449bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3450bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
3451bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3452bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
3453bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3454bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3455bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_connect(mNativeWindow.get(),
3456bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_CPU);
3457bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3458bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
3459bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3460bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
3461bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3462bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3463bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffers_geometry(mNativeWindow.get(), 1, 1,
3464bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            HAL_PIXEL_FORMAT_RGBX_8888);
3465bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3466bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffers_geometry failed: %s (%d)",
3467bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3468bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
3469bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3470bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
347187eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin    err = native_window_set_scaling_mode(mNativeWindow.get(),
347287eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
347387eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin    if (err != NO_ERROR) {
347487eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin        ALOGE("error pushing blank_frames: set_scaling_mode failed: %s (%d)",
347587eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin              strerror(-err), -err);
347687eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin        goto error;
3477bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3478bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3479bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_usage(mNativeWindow.get(),
3480bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            GRALLOC_USAGE_SW_WRITE_OFTEN);
3481bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3482bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_usage failed: %s (%d)",
3483bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3484bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
3485bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3486bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3487bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = mNativeWindow->query(mNativeWindow.get(),
3488bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs);
3489bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3490bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: MIN_UNDEQUEUED_BUFFERS query "
3491bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                "failed: %s (%d)", strerror(-err), -err);
3492bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
3493bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3494bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3495bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    numBufs = minUndequeuedBufs + 1;
3496bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffer_count(mNativeWindow.get(), numBufs);
3497bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3498bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffer_count failed: %s (%d)",
3499bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3500bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
3501bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3502bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3503bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We  push numBufs + 1 buffers to ensure that we've drawn into the same
3504bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // buffer twice.  This should guarantee that the buffer has been displayed
3505bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // on the screen and then been replaced, so an previous video frames are
3506bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // guaranteed NOT to be currently displayed.
3507bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    for (int i = 0; i < numBufs + 1; i++) {
35081e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        int fenceFd = -1;
35091e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &anb);
3510bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3511bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: dequeueBuffer failed: %s (%d)",
3512bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3513bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
3514bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3515bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3516bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
3517bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3518bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Fill the buffer with the a 1x1 checkerboard pattern ;)
3519bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        uint32_t* img = NULL;
3520bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
3521bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3522bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: lock failed: %s (%d)",
3523bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3524bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
3525bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3526bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3527bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        *img = 0;
3528bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3529bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->unlock();
3530bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3531bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: unlock failed: %s (%d)",
3532bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3533bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
3534bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3535bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3536bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->queueBuffer(mNativeWindow.get(),
35371e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                buf->getNativeBuffer(), -1);
3538bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3539bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: queueBuffer failed: %s (%d)",
3540bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3541bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
3542bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3543bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3544bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        anb = NULL;
3545bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3546bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3547bc098410be55f9d96f394b3981a0c482b83859b6Andreas Hubererror:
3548bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3549bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3550bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after an error.
3551bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (anb != NULL) {
35521e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis            mNativeWindow->cancelBuffer(mNativeWindow.get(), anb, -1);
3553bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3554bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3555bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_disconnect(mNativeWindow.get(),
3556bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
3557bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_connect(mNativeWindow.get(),
3558bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
3559bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3560bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
3561bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    } else {
3562bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after success.
3563bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_disconnect(mNativeWindow.get(),
3564bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
3565bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3566bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
3567bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3568bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
3569bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3570bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3571bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_connect(mNativeWindow.get(),
3572bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
3573bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3574bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
3575bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3576bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
3577bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3578bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3579bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return NO_ERROR;
3580bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3581bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber}
3582bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3585eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberACodec::PortDescription::PortDescription() {
3586eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3587eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3588496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t ACodec::requestIDRFrame() {
3589496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    if (!mIsEncoder) {
3590496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        return ERROR_UNSUPPORTED;
3591496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    }
3592496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
3593496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    OMX_CONFIG_INTRAREFRESHVOPTYPE params;
3594496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    InitOMXParams(&params);
3595496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
3596496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.nPortIndex = kPortIndexOutput;
3597496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.IntraRefreshVOP = OMX_TRUE;
3598496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
3599496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    return mOMX->setConfig(
3600496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            mNode,
3601496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            OMX_IndexConfigVideoIntraVOPRefresh,
3602496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            &params,
3603496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            sizeof(params));
3604496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
3605496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
3606eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubervoid ACodec::PortDescription::addBuffer(
3607eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        IOMX::buffer_id id, const sp<ABuffer> &buffer) {
3608eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBufferIDs.push_back(id);
3609eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBuffers.push_back(buffer);
3610eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3611eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3612eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersize_t ACodec::PortDescription::countBuffers() {
3613eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.size();
3614eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3615eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3616eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberIOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const {
3617eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.itemAt(index);
3618eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3619eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3620eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const {
3621eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBuffers.itemAt(index);
3622eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3623eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3624eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber////////////////////////////////////////////////////////////////////////////////
3625eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3626f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
3627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : AState(parentState),
3628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mCodec(codec) {
3629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3631ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas HuberACodec::BaseState::PortMode ACodec::BaseState::getPortMode(
3632ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
3633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return KEEP_BUFFERS;
3634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3636f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
3637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatInputBufferFilled:
3639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onInputBufferFilled(msg);
3641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatOutputBufferDrained:
3645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onOutputBufferDrained(msg);
3647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatOMXMessage:
3651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXMessage(msg);
3653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
36557cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
36567cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
36577cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
3658251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            // This may result in an app illegal state exception.
36597cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            ALOGE("Message 0x%x was not handled", msg->what());
36607cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
36617cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            return true;
36627cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
36637cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
3664ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        case ACodec::kWhatOMXDied:
3665ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        {
3666251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            // This will result in kFlagSawMediaServerDie handling in MediaCodec.
3667ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            ALOGE("OMX/mediaserver died, signalling error!");
3668ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT);
3669ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            break;
3670ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        }
3671ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
3674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3679f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
3680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t type;
3681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findInt32("type", &type));
3682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
36835e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // there is a possibility that this is an outstanding message for a
36845e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // codec that we have already destroyed
36855e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    if (mCodec->mNode == NULL) {
36865e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar        ALOGI("ignoring message as already freed component: %s",
36875e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar                msg->debugString().c_str());
36885e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar        return true;
36895e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    }
36905e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar
3691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::node_id nodeID;
3692609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("node", (int32_t*)&nodeID));
3693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(nodeID, mCodec->mNode);
3694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (type) {
3696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EVENT:
3697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t event, data1, data2;
3699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("event", &event));
3700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data1", &data1));
3701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data2", &data2));
3702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
37030af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            if (event == OMX_EventCmdComplete
37040af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data1 == OMX_CommandFlush
37050af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data2 == (int32_t)OMX_ALL) {
37060af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // Use of this notification is not consistent across
37070af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // implementations. We'll drop this notification and rely
37080af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // on flush-complete notifications on the individual port
37090af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // indices instead.
37100af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
37110af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                return true;
37120af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            }
37130af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
3714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEvent(
3715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_EVENTTYPE>(event),
3716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data1),
3717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data2));
3718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EMPTY_BUFFER_DONE:
3721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
3723609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
3724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEmptyBufferDone(bufferID);
3726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::FILL_BUFFER_DONE:
3729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
3731609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
3732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t rangeOffset, rangeLength, flags;
3734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs;
3735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_offset", &rangeOffset));
3737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_length", &rangeLength));
3738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("flags", &flags));
3739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt64("timestamp", &timeUs));
3740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXFillBufferDone(
3742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    bufferID,
3743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (size_t)rangeOffset, (size_t)rangeLength,
3744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (OMX_U32)flags,
3745784e24e386b088c05d653ab482f2e95cb53e3d01Andy Hung                    timeUs);
3746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
3750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3754f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEvent(
3755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (event != OMX_EventError) {
37573856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] EVENT(%d, 0x%08lx, 0x%08lx)",
3758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mCodec->mComponentName.c_str(), event, data1, data2);
3759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return false;
3761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
376329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block    ALOGE("[%s] ERROR(0x%08lx)", mCodec->mComponentName.c_str(), data1);
3764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3765251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // verify OMX component sends back an error we expect.
3766251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    OMX_ERRORTYPE omxError = (OMX_ERRORTYPE)data1;
3767251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (!isOMXError(omxError)) {
3768251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        ALOGW("Invalid OMX error %#x", omxError);
3769251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        omxError = OMX_ErrorUndefined;
3770251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
3771251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    mCodec->signalError(omxError);
3772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3775f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3776f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID) {
37773856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] onOMXEmptyBufferDone %p",
3778349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber         mCodec->mComponentName.c_str(), bufferID);
3779349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexInput, bufferID);
3782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
3784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3786d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    const sp<AMessage> &bufferMeta = info->mData->meta();
3787d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    void *mediaBuffer;
3788d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (bufferMeta->findPointer("mediaBuffer", &mediaBuffer)
3789d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && mediaBuffer != NULL) {
3790d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // We're in "store-metadata-in-buffers" mode, the underlying
3791d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // OMX component had access to data that's implicitly refcounted
3792d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // by this "mediaBuffer" object. Now that the OMX component has
3793d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // told us that it's done with the input buffer, we can decrement
3794d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // the mediaBuffer's reference count.
379596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
379696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        ALOGV("releasing mbuf %p", mediaBuffer);
379796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
3798d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ((MediaBuffer *)mediaBuffer)->release();
3799d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mediaBuffer = NULL;
3800d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3801d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        bufferMeta->setPointer("mediaBuffer", NULL);
3802d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
3803d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
3805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            postFillThisBuffer(info);
3812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();  // Not currently used
3818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3825f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
3826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
3827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
3831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
3833d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatFillThisBuffer);
3834609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    notify->setInt32("buffer-id", info->mBufferID);
3835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mData->meta()->clear();
38372d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    notify->setBuffer("buffer", info->mData);
3838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec->id());
3840609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    reply->setInt32("buffer-id", info->mBufferID);
3841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setMessage("reply", reply);
3843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->post();
3845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
3847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3849f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
3850f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
3851609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
38522d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    sp<ABuffer> buffer;
3853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t err = OK;
38545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool eos = false;
3855a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar    PortMode mode = getPortMode(kPortIndexInput);
38565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38572d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    if (!msg->findBuffer("buffer", &buffer)) {
3858a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar        /* these are unfilled buffers returned by client */
3859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findInt32("err", &err));
3860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
38617fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        if (err == OK) {
38627fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            /* buffers with no errors are returned on MediaCodec.flush */
38637fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            mode = KEEP_BUFFERS;
38647fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        } else {
38657fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            ALOGV("[%s] saw error %d instead of an input buffer",
38667fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                 mCodec->mComponentName.c_str(), err);
38677fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            eos = true;
38687fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        }
38693831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
38702d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber        buffer.clear();
3871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
38735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
38745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
38755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
38765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = ERROR_END_OF_STREAM;
38775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
38785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
3880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_UPSTREAM);
3881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
38875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (eos) {
3888dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (!mCodec->mPortEOS[kPortIndexInput]) {
3889dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
3890dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mInputEOSResult = err;
3891dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
3892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
38985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
3899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int64_t timeUs;
3900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
3901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
3903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t isCSD;
3905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
3906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
3907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
39095778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (eos) {
39105778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    flags |= OMX_BUFFERFLAG_EOS;
39115778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
39125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer != info->mData) {
3914d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGV("[%s] Needs to copy input data for buffer %p. (%p != %p)",
3915d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(),
3916d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         bufferID,
3917d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         buffer.get(), info->mData.get());
3918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    CHECK_LE(buffer->size(), info->mData->capacity());
3920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    memcpy(info->mData->data(), buffer->data(), buffer->size());
3921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3923078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
39243856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ codec specific data",
3925078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID);
39265778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else if (flags & OMX_BUFFERFLAG_EOS) {
39275778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] calling emptyBuffer %p w/ EOS",
39285778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str(), bufferID);
3929078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                } else {
3930d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3931d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGI("[%s] calling emptyBuffer %p w/ time %lld us",
3932d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
3933d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#else
39343856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ time %lld us",
3935078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
3936d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3937078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                }
3938349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3939d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3940d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ACodec::BufferStats stats;
3941d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
3942d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mFillBufferDoneTimeUs = -1ll;
3943d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mCodec->mBufferStats.add(timeUs, stats);
3944d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3945d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3946054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                if (mCodec->mStoreMetaDataInOutputBuffers) {
3947054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    // try to submit an output buffer for each input buffer
3948054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    PortMode outputMode = getPortMode(kPortIndexOutput);
3949054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3950054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    ALOGV("MetaDataBuffersToSubmit=%u portMode=%s",
3951054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            mCodec->mMetaDataBuffersToSubmit,
3952054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            (outputMode == FREE_BUFFERS ? "FREE" :
3953054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                             outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
3954054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    if (outputMode == RESUBMIT_BUFFERS) {
3955e53350373ac516257b4f8956ff1e3f1ac48f607eLajos Molnar                        mCodec->submitOutputMetaDataBuffer();
3956054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    }
3957054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                }
3958054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
3960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
3961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
3962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            buffer->size(),
3964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            flags,
3965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            timeUs),
3966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
3967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
39705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (!eos) {
39715778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    getMoreInputDataIfPossible();
39725778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
39735778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] Signalled EOS on the input port",
39745778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str());
39755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39765778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
39775778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mInputEOSResult = err;
39785778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
3979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
3980dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (err != ERROR_END_OF_STREAM) {
39813856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port "
3982dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         "due to error %d",
3983dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str(), err);
3984dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                } else {
39853856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port",
3986dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str());
3987dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
3988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
39893856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] calling emptyBuffer %p signalling EOS",
3990349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                     mCodec->mComponentName.c_str(), bufferID);
3991349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
3993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
3994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
3995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_BUFFERFLAG_EOS,
3998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0),
3999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexInput] = true;
4004dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                mCodec->mInputEOSResult = err;
4005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4008625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih
4009625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih        default:
4010625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
4011625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih            break;
4012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4015f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::getMoreInputDataIfPossible() {
4016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
4017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
4018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *eligible = NULL;
4021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
4023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
4024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
4026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
4027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // There's already a "read" pending.
4028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
4029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
4031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_US) {
4033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            eligible = info;
4034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (eligible == NULL) {
4038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
4039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(eligible);
4042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4044f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXFillBufferDone(
4045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferID,
4046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        size_t rangeOffset, size_t rangeLength,
4047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 flags,
4048784e24e386b088c05d653ab482f2e95cb53e3d01Andy Hung        int64_t timeUs) {
4049609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] onOMXFillBufferDone %u time %" PRId64 " us, flags = 0x%08x",
40505778822d86b0337407514b9372562b86edfa91cdAndreas Huber         mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
4051349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
4053d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4054d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
4055d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    index = mCodec->mBufferStats.indexOfKey(timeUs);
4056d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (index >= 0) {
4057d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
4058d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
4059d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4060d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ALOGI("frame PTS %lld: %lld",
4061d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                timeUs,
4062d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
4063d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4064d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mCodec->mBufferStats.removeItemsAt(index);
4065d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats = NULL;
4066d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
4067d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
4068d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
4070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
4071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
4073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4074054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mDequeuedAt = ++mCodec->mDequeueCounter;
4075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
4076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
4078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4081f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
40855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (rangeLength == 0 && !(flags & OMX_BUFFERFLAG_EOS)) {
4086609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                ALOGV("[%s] calling fillBuffer %u",
40875778822d86b0337407514b9372562b86edfa91cdAndreas Huber                     mCodec->mComponentName.c_str(), info->mBufferID);
4088349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
40895778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK_EQ(mCodec->mOMX->fillBuffer(
40905778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mCodec->mNode, info->mBufferID),
40915778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         (status_t)OK);
4092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
40935778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
40945778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
40955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
409631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4097577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            sp<AMessage> reply =
4098577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                new AMessage(kWhatOutputBufferDrained, mCodec->id());
4099577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
41004bdda35319d5f46efea2089b865c8a64816389cdMarco Nelissen            if (!mCodec->mSentFormat && rangeLength > 0) {
4101577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->sendFormatChange(reply);
41025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
4103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4104308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            if (mCodec->mUseMetadataOnEncoderOutput) {
4105308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                native_handle_t* handle =
4106308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        *(native_handle_t**)(info->mData->data() + 4);
4107308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setPointer("handle", handle);
4108308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeOffset", rangeOffset);
4109308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeLength", rangeLength);
4110308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            } else {
4111308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->setRange(rangeOffset, rangeLength);
4112308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            }
4113496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#if 0
411421ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen            if (mCodec->mNativeWindow == NULL) {
4115496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                if (IsIDR(info->mData)) {
4116496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                    ALOGI("IDR frame");
4117496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                }
41185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
411921ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen#endif
4120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
41218b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            if (mCodec->mSkipCutBuffer != NULL) {
41228b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                mCodec->mSkipCutBuffer->submit(info->mData);
41238b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            }
41245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mData->meta()->setInt64("timeUs", timeUs);
4125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
41265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4127d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatDrainThisBuffer);
4128609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            notify->setInt32("buffer-id", info->mBufferID);
41292d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            notify->setBuffer("buffer", info->mData);
41305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("flags", flags);
4131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4132609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            reply->setInt32("buffer-id", info->mBufferID);
4133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
41345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setMessage("reply", reply);
4135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
41365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->post();
41375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
4139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (flags & OMX_BUFFERFLAG_EOS) {
41415778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
41425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                sp<AMessage> notify = mCodec->mNotify->dup();
4144d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar                notify->setInt32("what", CodecBase::kWhatEOS);
4145dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                notify->setInt32("err", mCodec->mInputEOSResult);
4146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->post();
4147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexOutput] = true;
4149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
4156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
4158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
4159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4166f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
4167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
4168609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
4169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
4170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
4171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
4172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM);
4173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4174577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    android_native_rect_t crop;
4175577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    if (msg->findRect("crop",
4176577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            &crop.left, &crop.top, &crop.right, &crop.bottom)) {
4177577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar        CHECK_EQ(0, native_window_set_crop(
4178577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->mNativeWindow.get(), &crop));
4179577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    }
4180577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
4181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t render;
4182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mNativeWindow != NULL
41836aade6058521b0dbd35a9a4620f4d04f02f90444Marco Nelissen            && msg->findInt32("render", &render) && render != 0
418479ee2399b67c7a11042c5904dc1309712a76f8cbJianzheng Zhou            && info->mData != NULL && info->mData->size() != 0) {
41856fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        ATRACE_NAME("render");
4186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The client wants this buffer to be rendered.
4187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4188fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        int64_t timestampNs = 0;
4189fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        if (!msg->findInt64("timestampNs", &timestampNs)) {
4190fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // TODO: it seems like we should use the timestamp
4191fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // in the (media)buffer as it potentially came from
4192fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // an input surface, but we did not propagate it prior to
4193fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // API 20.  Perhaps check for target SDK version.
4194fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#if 0
4195fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            if (info->mData->meta()->findInt64("timeUs", &timestampNs)) {
419647aea1f7c58f5302b16822f9e7e1763f2af04ef5Lajos Molnar                ALOGV("using buffer PTS of %" PRId64, timestampNs);
4197fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar                timestampNs *= 1000;
4198fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            }
4199fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#endif
4200fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
4201fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
42025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err;
4203fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        err = native_window_set_buffers_timestamp(mCodec->mNativeWindow.get(), timestampNs);
4204fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        if (err != OK) {
4205fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            ALOGW("failed to set buffer timestamp: %d", err);
4206fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
4207fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
42085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if ((err = mCodec->mNativeWindow->queueBuffer(
4209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNativeWindow.get(),
42101e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                    info->mGraphicBuffer.get(), -1)) == OK) {
4211cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
4212cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        } else {
4213251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
4214cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
4215cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        }
4216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
42176fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        if (mCodec->mNativeWindow != NULL &&
42186fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar            (info->mData == NULL || info->mData->size() != 0)) {
42196fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar            ATRACE_NAME("frame-drop");
42206fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        }
4221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_US;
4222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
4225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
4230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // We cannot resubmit the buffer we just rendered, dequeue
4233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // the spare instead.
4234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info = mCodec->dequeueBufferFromNativeWindow();
4236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (!mCodec->mPortEOS[kPortIndexOutput]) {
4243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // We cannot resubmit the buffer we just rendered, dequeue
4245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // the spare instead.
4246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info = mCodec->dequeueBufferFromNativeWindow();
4248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
4249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4250c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                if (info != NULL) {
4251609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                    ALOGV("[%s] calling fillBuffer %u",
4252c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                         mCodec->mComponentName.c_str(), info->mBufferID);
4253349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4254c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
4255c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                             (status_t)OK);
4256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4257c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4258c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                }
4259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
4266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
4268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
4269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4276f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::UninitializedState::UninitializedState(ACodec *codec)
4277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4280c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::UninitializedState::stateEntered() {
4281c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("Now uninitialized");
4282ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4283ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (mDeathNotifier != NULL) {
4284ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mCodec->mOMX->asBinder()->unlinkToDeath(mDeathNotifier);
4285ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
4286ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
4287ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4288ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNativeWindow.clear();
4289ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNode = NULL;
4290ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mOMX.clear();
4291ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mQuirks = 0;
4292ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mFlags = 0;
4293308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    mCodec->mUseMetadataOnEncoderOutput = 0;
4294ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mComponentName.clear();
4295c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4296c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4297f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
4298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatSetup:
4302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onSetup(msg);
4304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
43095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case ACodec::kWhatAllocateComponent:
43105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
43115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            onAllocateComponent(msg);
43125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            handled = true;
43135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
43145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
43155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatShutdown:
4317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4318c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
4319c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
4320c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
432154b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            ALOGW_IF(keepComponentAllocated,
432254b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar                     "cannot keep component allocated on shutdown in Uninitialized state");
4323c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4325d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
4326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
4327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4329c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
4330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatFlush:
4333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4335d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
4336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
4337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4339c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
4340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
4344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4349f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::UninitializedState::onSetup(
4350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4351c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (onAllocateComponent(msg)
4352c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            && mCodec->mLoadedState->onConfigureComponent(msg)) {
4353c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mLoadedState->onStart();
4354c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
43555778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
43565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4357c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
43585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onAllocateComponent");
43595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4360c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    CHECK(mCodec->mNode == NULL);
43615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMXClient client;
4363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(client.connect(), (status_t)OK);
4364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<IOMX> omx = client.interface();
4366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4367ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec->id());
4368ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4369ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mDeathNotifier = new DeathNotifier(notify);
4370ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (omx->asBinder()->linkToDeath(mDeathNotifier) != OK) {
4371ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // This was a local binder, if it dies so do we, we won't care
4372ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // about any notifications in the afterlife.
4373ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
4374ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
4375ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4376e671207115fac3914134c61b336d5fa0242c68caAndreas Huber    Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs;
43775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    AString mime;
4379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
43805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString componentName;
4381d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint32_t quirks = 0;
43827791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen    int32_t encoder = false;
43835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findString("componentName", &componentName)) {
4384e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        ssize_t index = matchingCodecs.add();
4385e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        OMXCodec::CodecNameAndQuirks *entry = &matchingCodecs.editItemAt(index);
4386e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        entry->mName = String8(componentName.c_str());
4387afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
4388e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        if (!OMXCodec::findCodecQuirks(
4389e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                    componentName.c_str(), &entry->mQuirks)) {
4390e671207115fac3914134c61b336d5fa0242c68caAndreas Huber            entry->mQuirks = 0;
4391afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
43925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
43935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(msg->findString("mime", &mime));
43945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
43955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("encoder", &encoder)) {
43965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder = false;
43975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
43985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
43995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMXCodec::findMatchingCodecs(
44005778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mime.c_str(),
44015778822d86b0337407514b9372562b86edfa91cdAndreas Huber                encoder, // createEncoder
44025778822d86b0337407514b9372562b86edfa91cdAndreas Huber                NULL,  // matchComponentName
44035778822d86b0337407514b9372562b86edfa91cdAndreas Huber                0,     // flags
4404e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                &matchingCodecs);
44055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
44061065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
44071065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    sp<CodecObserver> observer = new CodecObserver;
44081065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    IOMX::node_id node = NULL;
44091065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
44101065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
44111065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            ++matchIndex) {
4412e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        componentName = matchingCodecs.itemAt(matchIndex).mName.string();
4413e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        quirks = matchingCodecs.itemAt(matchIndex).mQuirks;
4414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4415078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        pid_t tid = androidGetTid();
4416078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        int prevPriority = androidGetThreadPriority(tid);
4417078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
44181065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        status_t err = omx->allocateNode(componentName.c_str(), observer, &node);
4419078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, prevPriority);
4420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
44211065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        if (err == OK) {
44221065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            break;
44237a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He        } else {
44247a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He            ALOGW("Allocating component '%s' failed, try next one.", componentName.c_str());
44251065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
44261065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
44271065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        node = NULL;
44281065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    }
44291065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
4430c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    if (node == NULL) {
44315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!mime.empty()) {
44327791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen            ALOGE("Unable to instantiate a %scoder for type '%s'.",
44337791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen                    encoder ? "en" : "de", mime.c_str());
44345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
44357791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen            ALOGE("Unable to instantiate codec '%s'.", componentName.c_str());
44365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
4437c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
4438cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        mCodec->signalError(OMX_ErrorComponentNotFound);
4439c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
4440c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
4441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4442ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    notify = new AMessage(kWhatOMXMessage, mCodec->id());
4443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    observer->setNotificationMessage(notify);
4444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mComponentName = componentName;
4446ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    mCodec->mFlags = 0;
4447ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
4448ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (componentName.endsWith(".secure")) {
4449ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        mCodec->mFlags |= kFlagIsSecure;
44500167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
4451ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
4452ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
4453afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mCodec->mQuirks = quirks;
4454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mOMX = omx;
4455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mNode = node;
4456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
44575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
44585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
4459d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatComponentAllocated);
44605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setString("componentName", mCodec->mComponentName.c_str());
44615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
44625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4463c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4464c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mCodec->changeState(mCodec->mLoadedState);
4465c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4466c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
44675778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
44685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4469c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
4470c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4471c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas HuberACodec::LoadedState::LoadedState(ACodec *codec)
4472c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    : BaseState(codec) {
4473c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4474c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4475c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::stateEntered() {
4476c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
4477c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4478f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mPortEOS[kPortIndexInput] =
4479f6f38287b97ec69b169387add6458f859b770e65Andreas Huber        mCodec->mPortEOS[kPortIndexOutput] = false;
4480f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
4481f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mInputEOSResult = OK;
4482f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
4483054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mDequeueCounter = 0;
4484054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mMetaDataBuffersToSubmit = 0;
4485a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    mCodec->mRepeatFrameDelayUs = -1ll;
4486e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mInputFormat.clear();
4487e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mOutputFormat.clear();
4488054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4489c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (mCodec->mShutdownInProgress) {
4490c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
4491c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4492c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mShutdownInProgress = false;
4493c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mKeepComponentAllocated = false;
4494c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4495c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        onShutdown(keepComponentAllocated);
4496c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
449754b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    mCodec->mExplicitShutdown = false;
4498c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4499c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4500c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
4501c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (!keepComponentAllocated) {
4502c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK);
4503c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4504c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->changeState(mCodec->mUninitializedState);
4505c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
4506c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
450754b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    if (mCodec->mExplicitShutdown) {
450854b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        sp<AMessage> notify = mCodec->mNotify->dup();
4509d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
451054b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        notify->post();
451154b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        mCodec->mExplicitShutdown = false;
451254b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    }
4513c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4514c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4515c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
4516c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool handled = false;
4517c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4518c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    switch (msg->what()) {
4519c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatConfigureComponent:
4520c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
4521c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onConfigureComponent(msg);
4522c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
4523c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
4524c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
4525c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
45267cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
45277cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
45287cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            onCreateInputSurface(msg);
45297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
45307cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
45317cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
45327cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4533c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatStart:
4534c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
4535c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onStart();
4536c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
4537c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
4538c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
4539c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4540c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatShutdown:
4541c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
4542c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
4543c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
4544c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
4545c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
454654b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
4547c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onShutdown(keepComponentAllocated);
4548c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4549c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
4550c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
4551c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
4552c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4553c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatFlush:
4554c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
4555c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4556d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
4557c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->post();
4558c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4559c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
4560c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
4561c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
4562c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4563c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        default:
4564c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            return BaseState::onMessageReceived(msg);
4565c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
4566c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4567c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return handled;
4568c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4569c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4570c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onConfigureComponent(
45715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg) {
45725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onConfigureComponent");
45735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
45745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(mCodec->mNode != NULL);
45755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
45765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString mime;
45775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findString("mime", &mime));
45785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
45795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mCodec->configureCodec(mime.c_str(), msg);
45805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
45815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
4582c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        ALOGE("[%s] configureCodec returning error %d",
4583c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber              mCodec->mComponentName.c_str(), err);
4584c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber
4585251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
4586c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
45875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<RefBase> obj;
4590386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    if (msg->findObject("native-window", &obj)
45915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            && strncmp("OMX.google.", mCodec->mComponentName.c_str(), 11)) {
45921173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        sp<NativeWindowWrapper> nativeWindow(
45931173118eace0e9e347cb007f0da817cee87579edGlenn Kasten                static_cast<NativeWindowWrapper *>(obj.get()));
45941173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        CHECK(nativeWindow != NULL);
45951173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        mCodec->mNativeWindow = nativeWindow->getNativeWindow();
45961ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber
45971ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber        native_window_set_scaling_mode(
45981ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                mCodec->mNativeWindow.get(),
45991ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
4600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((status_t)OK, mCodec->initNativeWindow());
4602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
46035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
46045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
4605d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatComponentConfigured);
4606e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("input-format", mCodec->mInputFormat);
4607e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("output-format", mCodec->mOutputFormat);
46085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
46095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4610c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4611c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
46125778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
46135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
46147cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::LoadedState::onCreateInputSurface(
4615ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        const sp<AMessage> & /* msg */) {
46167cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    ALOGV("onCreateInputSurface");
46177cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
46187cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<AMessage> notify = mCodec->mNotify->dup();
4619d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatInputSurfaceCreated);
46207cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
46217cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<IGraphicBufferProducer> bufferProducer;
46227cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    status_t err;
46237cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
46247cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    err = mCodec->mOMX->createInputSurface(mCodec->mNode, kPortIndexInput,
46257cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            &bufferProducer);
4626a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
4627a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    if (err == OK && mCodec->mRepeatFrameDelayUs > 0ll) {
4628a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        err = mCodec->mOMX->setInternalOption(
4629a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                mCodec->mNode,
4630a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                kPortIndexInput,
4631a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY,
4632a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                &mCodec->mRepeatFrameDelayUs,
4633a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                sizeof(mCodec->mRepeatFrameDelayUs));
4634a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
4635a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (err != OK) {
4636a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            ALOGE("[%s] Unable to configure option to repeat previous "
4637a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  "frames (err %d)",
4638a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  mCodec->mComponentName.c_str(),
4639a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  err);
4640a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
4641a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
4642a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
46432c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    if (err == OK && mCodec->mMaxPtsGapUs > 0ll) {
464494ee4b708acfa941581160b267afb79192b1d816Chong Zhang        err = mCodec->mOMX->setInternalOption(
464594ee4b708acfa941581160b267afb79192b1d816Chong Zhang                mCodec->mNode,
464694ee4b708acfa941581160b267afb79192b1d816Chong Zhang                kPortIndexInput,
464794ee4b708acfa941581160b267afb79192b1d816Chong Zhang                IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP,
464894ee4b708acfa941581160b267afb79192b1d816Chong Zhang                &mCodec->mMaxPtsGapUs,
464994ee4b708acfa941581160b267afb79192b1d816Chong Zhang                sizeof(mCodec->mMaxPtsGapUs));
465094ee4b708acfa941581160b267afb79192b1d816Chong Zhang
465194ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (err != OK) {
465294ee4b708acfa941581160b267afb79192b1d816Chong Zhang            ALOGE("[%s] Unable to configure max timestamp gap (err %d)",
465372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    mCodec->mComponentName.c_str(),
465472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    err);
46552c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
46562c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
46572c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
46582c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    if (err == OK && mCodec->mTimePerCaptureUs > 0ll
46592c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            && mCodec->mTimePerFrameUs > 0ll) {
46602c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        int64_t timeLapse[2];
46612c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[0] = mCodec->mTimePerFrameUs;
46622c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[1] = mCodec->mTimePerCaptureUs;
46632c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        err = mCodec->mOMX->setInternalOption(
46642c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                mCodec->mNode,
46652c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                kPortIndexInput,
46662c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                IOMX::INTERNAL_OPTION_TIME_LAPSE,
46672c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                &timeLapse[0],
46682c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                sizeof(timeLapse));
46692c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
46702c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (err != OK) {
46712c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            ALOGE("[%s] Unable to configure time lapse (err %d)",
46722c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    mCodec->mComponentName.c_str(),
46732c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    err);
46742c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
46752c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
467672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
467772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (err == OK && mCodec->mCreateInputBuffersSuspended) {
467872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        bool suspend = true;
467972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        err = mCodec->mOMX->setInternalOption(
468072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                mCodec->mNode,
468172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                kPortIndexInput,
468272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                IOMX::INTERNAL_OPTION_SUSPEND,
468372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                &suspend,
468472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                sizeof(suspend));
468572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
468672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
468772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("[%s] Unable to configure option to suspend (err %d)",
468894ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  mCodec->mComponentName.c_str(),
468994ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  err);
469094ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
469194ee4b708acfa941581160b267afb79192b1d816Chong Zhang    }
469294ee4b708acfa941581160b267afb79192b1d816Chong Zhang
46937cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err == OK) {
46947cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setObject("input-surface",
46957cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                new BufferProducerWrapper(bufferProducer));
46967cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else {
46977cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // Can't use mCodec->signalError() here -- MediaCodec won't forward
46987cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // the error through because it's in the "configured" state.  We
46997cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // send a kWhatInputSurfaceCreated with an error value instead.
47007cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGE("[%s] onCreateInputSurface returning error %d",
47017cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                mCodec->mComponentName.c_str(), err);
47027cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setInt32("err", err);
47037cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
47047cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->post();
47057cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
47067cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4707c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onStart() {
47085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onStart");
47095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
47105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ(mCodec->mOMX->sendCommand(
47115778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
4712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
4713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->changeState(mCodec->mLoadedToIdleState);
4715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4719f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
4720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4723f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::LoadedToIdleState::stateEntered() {
47243856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
4725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4726cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    status_t err;
4727cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    if ((err = allocateBuffers()) != OK) {
472829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to allocate buffers after transitioning to IDLE state "
4729cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             "(error 0x%08x)",
4730cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             err);
4731cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
4732251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
473391bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber
473491bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber        mCodec->changeState(mCodec->mLoadedState);
4735cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    }
4736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4738f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::LoadedToIdleState::allocateBuffers() {
4739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
4740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
4742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
4743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mCodec->allocateBuffersOnPort(kPortIndexOutput);
4746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4748f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
4749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
475072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
4751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
47576507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
47586507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
47596507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
47606507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
47616507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
47626507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
47636463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatResume:
47646463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
47656463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We'll be active soon enough.
47666463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
47676463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
47686463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
47696463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatFlush:
47706463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
47716463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We haven't even started yet, so we're flushed alright...
47726463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            sp<AMessage> notify = mCodec->mNotify->dup();
4773d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
47746463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->post();
47756463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
47766463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
47776463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
4778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
4780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4783f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onOMXEvent(
4784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
4790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
4792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting),
4793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
4794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mIdleToExecutingState);
4796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4807f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
4808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4811f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToExecutingState::stateEntered() {
48123856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
4813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4815f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
4816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
481772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
4818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4824d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatResume:
4825d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
4826d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We'll be active soon enough.
4827d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
4828d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
4829d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
4830d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatFlush:
4831d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
4832d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We haven't even started yet, so we're flushed alright...
4833d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4834d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
4835d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->post();
4836d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
4837d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
4838d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
4839d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
48406507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
48416507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
48426507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
48436507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
48446507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
48456507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
4846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
4848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4850f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4851f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onOMXEvent(
4852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateExecuting);
4858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mExecutingState->resume();
4860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingState);
4861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4872f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingState::ExecutingState(ACodec *codec)
4873349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    : BaseState(codec),
4874349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber      mActive(false) {
4875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4877f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
4878ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
4879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
4880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4882054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputMetaBuffers() {
4883054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // submit as many buffers as there are input buffers with the codec
4884054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // in case we are in port reconfiguring
4885054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
4886054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
4887054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4888054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) {
4889054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            if (mCodec->submitOutputMetaDataBuffer() != OK)
4890054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                break;
4891054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
4892054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
48934dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
48944dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
48954dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
4896054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
4897054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4898054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitRegularOutputBuffers() {
4899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
4900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
4901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mCodec->mNativeWindow != NULL) {
4903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(info->mStatus == BufferInfo::OWNED_BY_US
4904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
4905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                continue;
4908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
4910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
4911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
49133856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] calling fillBuffer %p",
4914349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str(), info->mBufferID);
4915349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
4917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
4918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4923054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputBuffers() {
4924c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar    submitRegularOutputBuffers();
4925054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mCodec->mStoreMetaDataInOutputBuffers) {
4926054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        submitOutputMetaBuffers();
4927054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
4928054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
4929054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4930f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::resume() {
4931349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    if (mActive) {
49323856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] We're already active, no need to resume.",
4933349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str());
4934349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4935349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        return;
4936349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    }
4937349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    submitOutputBuffers();
4939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
49403cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    // Post all available input buffers
4941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_GT(mCodec->mBuffers[kPortIndexInput].size(), 0u);
49423cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); i++) {
49433cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
49443cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_US) {
49453cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar            postFillThisBuffer(info);
49463cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        }
49473cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    }
4948349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4949349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    mActive = true;
4950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4952f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::stateEntered() {
49533856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
4954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->processDeferredMessages();
4956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4958f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
4959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4964c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
4965c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
4966c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
4967c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4968c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mShutdownInProgress = true;
496954b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
4970c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mKeepComponentAllocated = keepComponentAllocated;
4971c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4972349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
4973349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
4975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
4976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
4977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingToIdleState);
4979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
49867a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong            ALOGV("[%s] ExecutingState flushing now "
4987d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                 "(codec owns %d/%d input, %d/%d output).",
4988d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mComponentName.c_str(),
4989d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
4990d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexInput].size(),
4991d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
4992d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexOutput].size());
4993d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4994349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
4995349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
4997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandFlush, OMX_ALL),
4998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
4999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mFlushingState);
5001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatResume:
5006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            resume();
5008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5013496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
5014496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
5015496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            status_t err = mCodec->requestIDRFrame();
5016496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            if (err != OK) {
5017496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                ALOGW("Requesting an IDR frame failed.");
5018496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            }
5019496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5020496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            handled = true;
5021496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
5022496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
5023496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5024a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
5025a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
5026a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
5027a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
5028a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5029a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = mCodec->setParameters(params);
5030a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5031a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> reply;
5032a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            if (msg->findMessage("reply", &reply)) {
5033a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->setInt32("err", err);
5034a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->post();
5035a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            }
5036a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5037a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            handled = true;
5038a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
5039a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
5040a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
50417cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
50427cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
50436507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
50447cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
50457cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
50467cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
50477cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
50484dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
50494dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        case kWhatSubmitOutputMetaDataBufferIfEOS:
50504dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        {
50514dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            if (mCodec->mPortEOS[kPortIndexInput] &&
50524dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    !mCodec->mPortEOS[kPortIndexOutput]) {
50534dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                status_t err = mCodec->submitOutputMetaDataBuffer();
50544dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                if (err == OK) {
50554dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
50564dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                }
50574dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            }
50584dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            return true;
50594dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        }
50604dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
5061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5069a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t ACodec::setParameters(const sp<AMessage> &params) {
5070a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    int32_t videoBitrate;
5071530fdbdc1b5491f3fbf172752834d1515701e142Lajos Molnar    if (params->findInt32("video-bitrate", &videoBitrate)) {
5072a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        OMX_VIDEO_CONFIG_BITRATETYPE configParams;
5073a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        InitOMXParams(&configParams);
5074a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nPortIndex = kPortIndexOutput;
5075a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nEncodeBitrate = videoBitrate;
5076a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5077a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        status_t err = mOMX->setConfig(
5078a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                mNode,
5079a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                OMX_IndexConfigVideoBitrate,
5080a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                &configParams,
5081a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                sizeof(configParams));
5082a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5083a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        if (err != OK) {
5084a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
5085a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                   videoBitrate, err);
5086a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5087a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            return err;
5088a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
5089a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    }
5090a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
509172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    int64_t skipFramesBeforeUs;
509272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (params->findInt64("skip-frames-before", &skipFramesBeforeUs)) {
509372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        status_t err =
509472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mOMX->setInternalOption(
509572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     mNode,
509672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     kPortIndexInput,
509772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     IOMX::INTERNAL_OPTION_START_TIME,
509872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     &skipFramesBeforeUs,
509972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     sizeof(skipFramesBeforeUs));
510072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
510172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
510272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("Failed to set parameter 'skip-frames-before' (err %d)", err);
510372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            return err;
510472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
510572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
510672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
5107e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    int32_t dropInputFrames;
5108e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    if (params->findInt32("drop-input-frames", &dropInputFrames)) {
5109e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        bool suspend = dropInputFrames != 0;
5110e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
5111b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err =
5112b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            mOMX->setInternalOption(
5113e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     mNode,
5114e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     kPortIndexInput,
5115e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     IOMX::INTERNAL_OPTION_SUSPEND,
5116e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     &suspend,
5117b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber                     sizeof(suspend));
5118b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
5119b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
5120b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err);
5121b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
5122b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
5123b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    }
5124b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
5125b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    int32_t dummy;
5126b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    if (params->findInt32("request-sync", &dummy)) {
5127b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err = requestIDRFrame();
5128b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
5129b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
5130b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Requesting a sync frame failed w/ err %d", err);
5131b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
5132b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
5133e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    }
5134e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
5135a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return OK;
5136a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
5137a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
51386507d14c6d10f93d390de62b9eed267f9b544985Andy McFaddenvoid ACodec::onSignalEndOfInputStream() {
51396507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    sp<AMessage> notify = mNotify->dup();
5140d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatSignaledInputEOS);
51416507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
51426507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    status_t err = mOMX->signalEndOfInputStream(mNode);
51436507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    if (err != OK) {
51446507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        notify->setInt32("err", err);
51456507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    }
51466507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->post();
51476507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden}
51486507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
5149f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onOMXEvent(
5150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventPortSettingsChanged:
5153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
5155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
515631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
5157054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mCodec->mMetaDataBuffersToSubmit = 0;
5158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
5159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
5160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_CommandPortDisable, kPortIndexOutput),
5161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
5162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5163349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                mCodec->freeOutputBuffersNotOwnedByComponent();
5164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
516631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            } else if (data2 == OMX_IndexConfigCommonOutputCrop) {
516731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
5168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
51693856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08lx",
5170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->mComponentName.c_str(), data2);
5171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventBufferFlag:
5177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5188f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
5189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ACodec *codec)
5190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5193f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
5194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
5195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput) {
5196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return FREE_BUFFERS;
5197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
5200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
5202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5204f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onMessageReceived(
5205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
5206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5211349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case kWhatResume:
5212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5213349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            if (msg->what() == kWhatResume) {
52143856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
5215349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            }
5216349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
5218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5230f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::OutputPortSettingsChangedState::stateEntered() {
52313856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now handling output port settings change",
5232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mCodec->mComponentName.c_str());
5233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5235f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onOMXEvent(
5236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
5241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
5242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
52433856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now disabled.",
5244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
5245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mCodec->mBuffers[kPortIndexOutput].isEmpty());
5247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mDealer[kPortIndexOutput].clear();
5248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
5250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput),
5251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
5252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5253cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                status_t err;
5254cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                if ((err = mCodec->allocateBuffersOnPort(
5255cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                                kPortIndexOutput)) != OK) {
525629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("Failed to allocate output port buffers after "
5257cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         "port reconfiguration (error 0x%08x)",
5258cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         err);
5259cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
5260251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5261d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
5262755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // This is technically not correct, but appears to be
5263755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the only way to free the component instance.
5264755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // Controlled transitioning from excecuting->idle
5265755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // and idle->loaded seem impossible probably because
5266755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the output port never finishes re-enabling.
5267755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mShutdownInProgress = true;
5268755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mKeepComponentAllocated = false;
5269755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->changeState(mCodec->mLoadedState);
5270cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                }
5271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
5273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
5274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
5275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
527631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
527731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
52783856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now reenabled.",
5279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
5280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5281349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                if (mCodec->mExecutingState->active()) {
5282349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    mCodec->mExecutingState->submitOutputBuffers();
5283349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                }
5284349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mExecutingState);
5286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
5288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
5291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
5295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5300f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
53015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : BaseState(codec),
53025778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mComponentNowIdle(false) {
5303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5305f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
5306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
5312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
5313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
5314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
5320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5333f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::stateEntered() {
53343856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
533531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
53365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mComponentNowIdle = false;
533731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mCodec->mSentFormat = false;
5338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5340f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onOMXEvent(
5341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
5346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
5347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
53485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mComponentNowIdle = true;
53495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            changeStateIfWeOwnAllBuffers();
5351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5355349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
5356349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventBufferFlag:
5357349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
5358349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We're shutting down and don't care about this anymore.
5359349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
5360349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
5361349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
53660af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
5367f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
53685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
5369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->sendCommand(
5370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded),
5371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
5372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexInput), (status_t)OK);
5374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexOutput), (status_t)OK);
5375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
53760167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown)
53770167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && mCodec->mNativeWindow != NULL) {
5378bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // We push enough 1x1 blank buffers to ensure that one of
5379bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // them has made it to the display.  This allows the OMX
5380bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // component teardown to zero out any protected buffers
5381bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // without the risk of scanning out one of those buffers.
5382bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            mCodec->pushBlankBuffersToNativeWindow();
5383bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
5384bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
5385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mIdleToLoadedState);
5386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5389f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onInputBufferFilled(
5390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
5391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
5392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
5394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5396f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onOutputBufferDrained(
5397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
5398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
5399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
5401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5405f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
5406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5409f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
5410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
5416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
5424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
5425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
5426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5437f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToLoadedState::stateEntered() {
54383856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
5439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5441f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onOMXEvent(
5442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
5447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateLoaded);
5448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5449c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->changeState(mCodec->mLoadedState);
5450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5461f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::FlushingState::FlushingState(ACodec *codec)
5462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5465f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::stateEntered() {
54663856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
5467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
5469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5471f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
5472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
5478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing this right now.
5484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5496f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onOMXEvent(
5497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
54987a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] FlushingState onOMXEvent(%d,%ld)",
5499d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            mCodec->mComponentName.c_str(), event, data1);
5500d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
5501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandFlush);
5505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
5507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(!mFlushComplete[data2]);
5508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mFlushComplete[data2] = true;
5509e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber
5510e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                if (mFlushComplete[kPortIndexInput]
5511e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                        && mFlushComplete[kPortIndexOutput]) {
5512e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                    changeStateIfWeOwnAllBuffers();
5513e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                }
5514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
5515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, OMX_ALL);
5516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexInput]);
5517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexOutput]);
5518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                changeStateIfWeOwnAllBuffers();
5520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5525349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
5526349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
5527349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec->id());
5528349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("type", omx_message::EVENT);
5529609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            msg->setInt32("node", mCodec->mNode);
5530349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("event", event);
5531349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data1", data1);
5532349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data2", data2);
5533349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
55343856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
5535349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                 mCodec->mComponentName.c_str());
5536349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5537349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mCodec->deferMessage(msg);
5538349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5539349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
5540349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
5541349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
5547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5549f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
5550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
5551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
5553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5555f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
5556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
5557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
5559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5561f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
5562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mFlushComplete[kPortIndexInput]
5563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mFlushComplete[kPortIndexOutput]
5564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mCodec->allYourBuffersAreBelongToUs()) {
55657e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // We now own all buffers except possibly those still queued with
55667e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // the native window for rendering. Let's get those back as well.
55677e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
55687e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
5569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
5570d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatFlushCompleted);
5571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->post();
5572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->mPortEOS[kPortIndexInput] =
5574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mPortEOS[kPortIndexOutput] = false;
5575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5576dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber        mCodec->mInputEOSResult = OK;
5577dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
5578f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        if (mCodec->mSkipCutBuffer != NULL) {
5579f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen            mCodec->mSkipCutBuffer->clear();
5580f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        }
5581f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen
5582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mExecutingState);
5583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
5587