ACodec.cpp revision 251d4be8aa5ab80bc915a82a2420233bdc62018e
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);
816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelBufferToNativeWindow(info);
817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
822054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputMetaDataBuffers() {
823054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
824054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
825054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
826054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
827054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
828e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    mNumUndequeuedBuffers = minUndequeuedBuffers;
829054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
830609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Allocating %u meta buffers on output port",
831054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount);
832054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
833054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    size_t totalSize = bufferCount * 8;
834054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mDealer[kPortIndexOutput] = new MemoryDealer(totalSize, "ACodec");
835054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
836054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // Dequeue buffers and send them to OMX
837054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
838054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo info;
839054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
840054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mGraphicBuffer = NULL;
841054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mDequeuedAt = mDequeueCounter;
842054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
843054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        sp<IMemory> mem = mDealer[kPortIndexOutput]->allocate(
844054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                sizeof(struct VideoDecoderOutputMetaData));
845054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(mem.get() != NULL);
846054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(mem->pointer(), mem->size());
847054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
848054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // we use useBuffer for metadata regardless of quirks
849054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        err = mOMX->useBuffer(
850054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mNode, kPortIndexOutput, mem, &info.mBufferID);
851054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
852054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        mBuffers[kPortIndexOutput].push(info);
853054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
854609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGV("[%s] allocated meta buffer with ID %u (pointer = %p)",
855054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mComponentName.c_str(), info.mBufferID, mem->pointer());
856054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
857054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
858054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mMetaDataBuffersToSubmit = bufferCount - minUndequeuedBuffers;
859054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
860054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
861054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
862054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::submitOutputMetaDataBuffer() {
863054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mStoreMetaDataInOutputBuffers);
864054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mMetaDataBuffersToSubmit == 0)
865054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return OK;
866054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
867054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *info = dequeueBufferFromNativeWindow();
868054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (info == NULL)
869054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return ERROR_IO;
870054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
871609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] submitting output meta buffer ID %u for graphic buffer %p",
872054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          mComponentName.c_str(), info->mBufferID, info->mGraphicBuffer.get());
873054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
874054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    --mMetaDataBuffersToSubmit;
875054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK_EQ(mOMX->fillBuffer(mNode, info->mBufferID),
876054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             (status_t)OK);
877054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
878054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
879054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return OK;
880054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
881054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
882f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
885609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Calling cancelBuffer on buffer %u",
886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mComponentName.c_str(), info->mBufferID);
887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int err = mNativeWindow->cancelBuffer(
8891e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        mNativeWindow.get(), info->mGraphicBuffer.get(), -1);
890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, 0);
892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
898f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
8998ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev    ANativeWindowBuffer *buf;
9001e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    int fenceFd = -1;
901054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mNativeWindow.get() != NULL);
9021e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    if (native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf) != 0) {
90329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("dequeueBuffer failed.");
904c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber        return NULL;
905c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
907054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *oldest = NULL;
908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
912054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mGraphicBuffer != NULL &&
913054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            info->mGraphicBuffer->handle == buf->handle) {
914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus,
915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (int)BufferInfo::OWNED_BY_NATIVE_WINDOW);
916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
921054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
922054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW &&
923054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (oldest == NULL ||
924054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             // avoid potential issues from counter rolling over
925054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mDequeueCounter - info->mDequeuedAt >
926054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    mDequeueCounter - oldest->mDequeuedAt)) {
927054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            oldest = info;
928054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
929054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
930054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
931054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (oldest) {
932054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(mStoreMetaDataInOutputBuffers);
933054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
934054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // discard buffer in LRU info and replace with new buffer
935054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mGraphicBuffer = new GraphicBuffer(buf, false);
936054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mStatus = BufferInfo::OWNED_BY_US;
937054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
938d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        mOMX->updateGraphicBufferInMeta(
939d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                mNode, kPortIndexOutput, oldest->mGraphicBuffer,
940d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                oldest->mBufferID);
941054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
942d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        VideoDecoderOutputMetaData *metaData =
943d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar            reinterpret_cast<VideoDecoderOutputMetaData *>(
944d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                    oldest->mData->base());
945d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        CHECK_EQ(metaData->eType, kMetadataBufferTypeGrallocSource);
946d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar
947d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
948054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                oldest - &mBuffers[kPortIndexOutput][0],
949054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mDequeueCounter - oldest->mDequeuedAt,
950d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                metaData->pHandle,
951d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                oldest->mGraphicBuffer->handle, oldest->mData->base());
952054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
953054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return oldest;
954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
961f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[portIndex].size(); i-- > 0;) {
963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, freeBuffer(portIndex, i));
964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDealer[portIndex].clear();
967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
971349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huberstatus_t ACodec::freeOutputBuffersNotOwnedByComponent() {
972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9762ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // At this time some buffers may still be with the component
9772ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // or being drained.
9782ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT &&
9792ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar            info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) {
980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK, freeBuffer(kPortIndexOutput, i));
981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
987f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(info->mStatus == BufferInfo::OWNED_BY_US
991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput && mNativeWindow != NULL
994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && info->mStatus == BufferInfo::OWNED_BY_US) {
995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, cancelBufferToNativeWindow(info));
996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(mOMX->freeBuffer(
999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, portIndex, info->mBufferID),
1000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
1001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mBuffers[portIndex].removeAt(i);
1003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1007f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::findBufferByID(
1008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        uint32_t portIndex, IOMX::buffer_id bufferID,
1009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ssize_t *index) {
1010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
1011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
1012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mBufferID == bufferID) {
1014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (index != NULL) {
1015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                *index = i;
1016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
1018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
1022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
1024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10265778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setComponentRole(
1027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        bool isEncoder, const char *mime) {
1028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    struct MimeToRole {
1029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime;
1030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *decoderRole;
1031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *encoderRole;
1032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
1033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const MimeToRole kMimeToRole[] = {
1035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG,
1036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.mp3", "audio_encoder.mp3" },
10372944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
10382944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp1", "audio_encoder.mp1" },
10392944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
10402944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp2", "audio_encoder.mp2" },
1041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_NB,
1042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrnb", "audio_encoder.amrnb" },
1043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_WB,
1044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrwb", "audio_encoder.amrwb" },
1045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AAC,
1046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.aac", "audio_encoder.aac" },
1047729de186450f78c099637e1fce743fe531862c52Andreas Huber        { MEDIA_MIMETYPE_AUDIO_VORBIS,
1048729de186450f78c099637e1fce743fe531862c52Andreas Huber            "audio_decoder.vorbis", "audio_encoder.vorbis" },
1049bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian        { MEDIA_MIMETYPE_AUDIO_OPUS,
1050bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian            "audio_decoder.opus", "audio_encoder.opus" },
1051c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_MLAW,
1052c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" },
1053c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_ALAW,
1054c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711alaw", "audio_encoder.g711alaw" },
1055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_AVC,
1056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.avc", "video_encoder.avc" },
10572472b1c0d63454e5d90a982bd6c555de6c3127bdRachad        { MEDIA_MIMETYPE_VIDEO_HEVC,
10582472b1c0d63454e5d90a982bd6c555de6c3127bdRachad            "video_decoder.hevc", "video_encoder.hevc" },
1059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_MPEG4,
1060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.mpeg4", "video_encoder.mpeg4" },
1061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_H263,
1062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.h263", "video_encoder.h263" },
106394705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP8,
106494705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp8", "video_encoder.vp8" },
106594705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP9,
106694705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp9", "video_encoder.vp9" },
1067ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        { MEDIA_MIMETYPE_AUDIO_RAW,
1068ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            "audio_decoder.raw", "audio_encoder.raw" },
10692f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        { MEDIA_MIMETYPE_AUDIO_FLAC,
10702f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            "audio_decoder.flac", "audio_encoder.flac" },
1071ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        { MEDIA_MIMETYPE_AUDIO_MSGSM,
1072ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen            "audio_decoder.gsm", "audio_encoder.gsm" },
1073774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu        { MEDIA_MIMETYPE_VIDEO_MPEG2,
1074774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu            "video_decoder.mpeg2", "video_encoder.mpeg2" },
107597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        { MEDIA_MIMETYPE_AUDIO_AC3,
107697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            "audio_decoder.ac3", "audio_encoder.ac3" },
1077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
1078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const size_t kNumMimeToRole =
1080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
1081f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    size_t i;
1083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (i = 0; i < kNumMimeToRole; ++i) {
1084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcasecmp(mime, kMimeToRole[i].mime)) {
1085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1086f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1089f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (i == kNumMimeToRole) {
10905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_UNSUPPORTED;
1091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    const char *role =
1094f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        isEncoder ? kMimeToRole[i].encoderRole
1095f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                  : kMimeToRole[i].decoderRole;
1096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (role != NULL) {
1098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_PARAM_COMPONENTROLETYPE roleParams;
1099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        InitOMXParams(&roleParams);
1100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        strncpy((char *)roleParams.cRole,
1102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                role, OMX_MAX_STRINGNAME_SIZE - 1);
1103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
1105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->setParameter(
1107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamStandardComponentRole,
1108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &roleParams, sizeof(roleParams));
1109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
11115ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("[%s] Failed to set standard component role '%s'.",
1112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 mComponentName.c_str(), role);
11135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
1115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
11175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
1119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
11215778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::configureCodec(
1122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime, const sp<AMessage> &msg) {
11235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t encoder;
11245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("encoder", &encoder)) {
11255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        encoder = false;
11265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1128e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    sp<AMessage> inputFormat = new AMessage();
1129e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    sp<AMessage> outputFormat = new AMessage();
1130e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
11315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mIsEncoder = encoder;
1132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
11335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setComponentRole(encoder /* isEncoder */, mime);
11345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
11365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
11375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
11385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitRate = 0;
11402f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    // FLAC encoder doesn't need a bitrate, other encoders do
11412f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
11422f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            && !msg->findInt32("bitrate", &bitRate)) {
11435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
11445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
11455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1146d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    int32_t storeMeta;
1147d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (encoder
1148d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && msg->findInt32("store-metadata-in-buffers", &storeMeta)
1149d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && storeMeta != 0) {
1150d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE);
1151d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1152d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (err != OK) {
1153308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              ALOGE("[%s] storeMetaDataInBuffers (input) failed w/ err %d",
1154308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    mComponentName.c_str(), err);
1155d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1156308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              return err;
1157308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang          }
1158308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang      }
1159d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1160308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t prependSPSPPS = 0;
11613a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    if (encoder
11623a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
11633a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && prependSPSPPS != 0) {
11643a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        OMX_INDEXTYPE index;
11653a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        err = mOMX->getExtensionIndex(
11663a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                mNode,
11673a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                "OMX.google.android.index.prependSPSPPSToIDRFrames",
11683a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                &index);
11693a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
11703a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err == OK) {
11713a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            PrependSPSPPSToIDRFramesParams params;
11723a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            InitOMXParams(&params);
11733a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            params.bEnable = OMX_TRUE;
11743a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
11753a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            err = mOMX->setParameter(
11763a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                    mNode, index, &params, sizeof(params));
11773a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
11783a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
11793a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err != OK) {
11803a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            ALOGE("Encoder could not be configured to emit SPS/PPS before "
11813a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                  "IDR frames. (err %d)", err);
11823a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
11833a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            return err;
11843a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
11853a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    }
11863a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
1187308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // Only enable metadata mode on encoder output if encoder can prepend
1188308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // sps/pps to idr frames, since in metadata mode the bitstream is in an
1189308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // opaque handle, to which we don't have access.
1190308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t video = !strncasecmp(mime, "video/", 6);
1191308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (encoder && video) {
1192308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS
1193308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && msg->findInt32("store-metadata-in-buffers-output", &storeMeta)
1194308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && storeMeta != 0);
1195308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1196308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, enable);
1197308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1198308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        if (err != OK) {
1199308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            ALOGE("[%s] storeMetaDataInBuffers (output) failed w/ err %d",
1200308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                mComponentName.c_str(), err);
1201308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = 0;
1202308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        } else {
1203308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = enable;
1204308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        }
1205a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
1206a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (!msg->findInt64(
1207a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    "repeat-previous-frame-after",
1208a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    &mRepeatFrameDelayUs)) {
1209a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            mRepeatFrameDelayUs = -1ll;
1210a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
121194ee4b708acfa941581160b267afb79192b1d816Chong Zhang
121294ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (!msg->findInt64("max-pts-gap-to-encoder", &mMaxPtsGapUs)) {
12132c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mMaxPtsGapUs = -1ll;
12142c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
12152c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
12162c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (!msg->findInt64("time-lapse", &mTimePerCaptureUs)) {
12172c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mTimePerCaptureUs = -1ll;
121894ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
121972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
122072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (!msg->findInt32(
122172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    "create-input-buffers-suspended",
122272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    (int32_t*)&mCreateInputBuffersSuspended)) {
122372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mCreateInputBuffersSuspended = false;
122472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
1225308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    }
1226308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1227054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // Always try to enable dynamic output buffers on native surface
1228054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    sp<RefBase> obj;
1229054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    int32_t haveNativeWindow = msg->findObject("native-window", &obj) &&
1230054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            obj != NULL;
1231054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mStoreMetaDataInOutputBuffers = false;
1232e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if (video && !encoder) {
1233e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        inputFormat->setInt32("adaptive-playback", false);
1234e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
1235054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (!encoder && video && haveNativeWindow) {
1236054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, OMX_TRUE);
1237054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (err != OK) {
1238054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d",
1239054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                  mComponentName.c_str(), err);
1240fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1241fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // if adaptive playback has been requested, try JB fallback
1242fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // NOTE: THIS FALLBACK MECHANISM WILL BE REMOVED DUE TO ITS
1243fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // LARGE MEMORY REQUIREMENT
1244fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1245fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // we will not do adaptive playback on software accessed
1246fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // surfaces as they never had to respond to changes in the
1247fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // crop window, and we don't trust that they will be able to.
1248fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            int usageBits = 0;
1249fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            bool canDoAdaptivePlayback;
1250fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1251fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            sp<NativeWindowWrapper> windowWrapper(
1252fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    static_cast<NativeWindowWrapper *>(obj.get()));
1253fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            sp<ANativeWindow> nativeWindow = windowWrapper->getNativeWindow();
1254fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1255fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            if (nativeWindow->query(
1256fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    nativeWindow.get(),
1257fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    NATIVE_WINDOW_CONSUMER_USAGE_BITS,
1258fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    &usageBits) != OK) {
1259fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                canDoAdaptivePlayback = false;
1260fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            } else {
1261fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                canDoAdaptivePlayback =
1262fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    (usageBits &
1263fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                            (GRALLOC_USAGE_SW_READ_MASK |
1264fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                             GRALLOC_USAGE_SW_WRITE_MASK)) == 0;
1265fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
1266fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1267fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            int32_t maxWidth = 0, maxHeight = 0;
1268fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            if (canDoAdaptivePlayback &&
1269fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                msg->findInt32("max-width", &maxWidth) &&
1270fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                msg->findInt32("max-height", &maxHeight)) {
127184333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber                ALOGV("[%s] prepareForAdaptivePlayback(%dx%d)",
1272fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                      mComponentName.c_str(), maxWidth, maxHeight);
1273fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1274fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                err = mOMX->prepareForAdaptivePlayback(
1275fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        mNode, kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight);
1276fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                ALOGW_IF(err != OK,
1277fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        "[%s] prepareForAdaptivePlayback failed w/ err %d",
1278fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        mComponentName.c_str(), err);
1279e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
1280e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                if (err == OK) {
1281e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    inputFormat->setInt32("max-width", maxWidth);
1282e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    inputFormat->setInt32("max-height", maxHeight);
1283e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    inputFormat->setInt32("adaptive-playback", true);
1284e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
1285fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
1286fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // allow failure
1287054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = OK;
1288054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
1289054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            ALOGV("[%s] storeMetaDataInBuffers succeeded", mComponentName.c_str());
1290054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            mStoreMetaDataInOutputBuffers = true;
1291e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            inputFormat->setInt32("adaptive-playback", true);
1292054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
12930167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber
12940167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        int32_t push;
12950167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if (msg->findInt32("push-blank-buffers-on-shutdown", &push)
12960167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && push != 0) {
12970167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber            mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
12980167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        }
1299e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang
1300e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        int32_t rotationDegrees;
1301e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        if (msg->findInt32("rotation-degrees", &rotationDegrees)) {
1302e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            mRotationDegrees = rotationDegrees;
1303e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        } else {
1304e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            mRotationDegrees = 0;
1305e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        }
1306054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1307054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1308308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (video) {
13095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (encoder) {
13105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupVideoEncoder(mime, msg);
13115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
131289869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            err = setupVideoDecoder(mime, msg);
13135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
131442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
131542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        int32_t numChannels, sampleRate;
131642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        if (!msg->findInt32("channel-count", &numChannels)
131742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
131842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // Since we did not always check for these, leave them optional
131942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // and have the decoder figure it all out.
132042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = OK;
132142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        } else {
132242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = setupRawAudioFormat(
132342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    encoder ? kPortIndexInput : kPortIndexOutput,
132442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    sampleRate,
132542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    numChannels);
132642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        }
1327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
1328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t numChannels, sampleRate;
13295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)
13305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
13315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
13325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
1333aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            int32_t isADTS, aacProfile;
1334b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            int32_t sbrMode;
1335ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            if (!msg->findInt32("is-adts", &isADTS)) {
1336ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                isADTS = 0;
1337ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
1338aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (!msg->findInt32("aac-profile", &aacProfile)) {
1339aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                aacProfile = OMX_AUDIO_AACObjectNull;
1340aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
1341b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            if (!msg->findInt32("aac-sbr-mode", &sbrMode)) {
1342b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                sbrMode = -1;
1343b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            }
1344ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1345ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            err = setupAACCodec(
13464471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    encoder, numChannels, sampleRate, bitRate, aacProfile,
1347b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                    isADTS != 0, sbrMode);
13485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
1349729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
13505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
1351729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
13525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
1353729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
1354729de186450f78c099637e1fce743fe531862c52Andreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
1355729de186450f78c099637e1fce743fe531862c52Andreas Huber        // These are PCM-like formats with a fixed sample rate but
1356729de186450f78c099637e1fce743fe531862c52Andreas Huber        // a variable number of channels.
1357729de186450f78c099637e1fce743fe531862c52Andreas Huber
1358729de186450f78c099637e1fce743fe531862c52Andreas Huber        int32_t numChannels;
13595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)) {
13605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
13615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
13625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupG711Codec(encoder, numChannels);
13635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13642f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
13652f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        int32_t numChannels, sampleRate, compressionLevel = -1;
13662f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (encoder &&
13672f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                (!msg->findInt32("channel-count", &numChannels)
13682f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                        || !msg->findInt32("sample-rate", &sampleRate))) {
13692f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("missing channel count or sample rate for FLAC encoder");
13702f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            err = INVALID_OPERATION;
13712f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        } else {
13722f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            if (encoder) {
1373516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                if (!msg->findInt32(
1374516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                            "flac-compression-level", &compressionLevel)) {
13752f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 5;// default FLAC compression level
13762f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel < 0) {
1377516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1378516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 0",
1379516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
13802f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 0;
13812f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel > 8) {
1382516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1383516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 8",
1384516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
13852f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 8;
13862f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                }
13872f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            }
1388516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            err = setupFlacCodec(
1389516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    encoder, numChannels, sampleRate, compressionLevel);
13902f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
1391ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
1392ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        int32_t numChannels, sampleRate;
1393ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        if (encoder
1394ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("channel-count", &numChannels)
1395ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
1396ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = INVALID_OPERATION;
1397ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        } else {
1398ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
1399ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        }
140097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AC3)) {
140197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t numChannels;
140297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t sampleRate;
140397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        if (!msg->findInt32("channel-count", &numChannels)
140497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                || !msg->findInt32("sample-rate", &sampleRate)) {
140597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = INVALID_OPERATION;
140697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        } else {
140797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = setupAC3Codec(encoder, numChannels, sampleRate);
140897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        }
14095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1410729de186450f78c099637e1fce743fe531862c52Andreas Huber
14114471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    if (err != OK) {
14124471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber        return err;
14134471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    }
14144471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber
14158b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
14168b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderDelay = 0;
14178b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
14189806555d3930be43e11106281dee354820ac1c88Andreas Huber
14198b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
14208b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderPadding = 0;
14218b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
14228b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen
14239806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (msg->findInt32("channel-mask", &mChannelMask)) {
14249806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = true;
14259806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else {
14269806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = false;
14279806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
14289806555d3930be43e11106281dee354820ac1c88Andreas Huber
1429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t maxInputSize;
1430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (msg->findInt32("max-input-size", &maxInputSize)) {
14315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
1432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
14335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
1434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
14355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1436e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ(getPortFormat(kPortIndexInput, inputFormat), (status_t)OK);
1437e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ(getPortFormat(kPortIndexOutput, outputFormat), (status_t)OK);
1438e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mInputFormat = inputFormat;
1439e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mOutputFormat = outputFormat;
1440e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
14415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
1442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1444f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
1445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
1447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
1448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (def.nBufferSize >= size) {
1457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
1458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nBufferSize = size;
1461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
1463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->getParameter(
1470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(def.nBufferSize >= size);
1477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14815778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::selectAudioPortFormat(
14825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
14835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_AUDIO_PARAM_PORTFORMATTYPE format;
14845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&format);
14855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    format.nPortIndex = portIndex;
14875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (OMX_U32 index = 0;; ++index) {
14885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        format.nIndex = index;
14895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
14915778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioPortFormat,
14925778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &format, sizeof(format));
14935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
14955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (format.eEncoding == desiredFormat) {
14995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
15005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
15045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format));
15055778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
15065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15075778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAACCodec(
1508aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        bool encoder, int32_t numChannels, int32_t sampleRate,
1509b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        int32_t bitRate, int32_t aacProfile, bool isADTS, int32_t sbrMode) {
1510ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (encoder && isADTS) {
1511ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return -EINVAL;
1512ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
1513ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
15145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setupRawAudioFormat(
15155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
15165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sampleRate,
15175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            numChannels);
15185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
15205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
15215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (encoder) {
15245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
15255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
15275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
15285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
15315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
15325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = kPortIndexOutput;
15335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
15355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
15365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
15385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
15395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.bFlagErrorConcealment = OMX_TRUE;
15425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
15435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
15455778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
15465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
15485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
15495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
15525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&profile);
15535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nPortIndex = kPortIndexOutput;
15545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
15565778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
15575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
15595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
15605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nChannels = numChannels;
15635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eChannelMode =
15655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (numChannels == 1)
15665778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
15675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nSampleRate = sampleRate;
15695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nBitRate = bitRate;
15705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAudioBandWidth = 0;
15715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nFrameLength = 0;
15725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACtools = OMX_AUDIO_AACToolAll;
15735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACERtools = OMX_AUDIO_AACERNone;
1574aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
15755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
1576b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        switch (sbrMode) {
1577b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 0:
1578b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // disable sbr
1579b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
1580b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
1581b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
1582b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 1:
1583b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable single-rate sbr
1584b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
1585b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
1586b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
1587b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 2:
1588b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable dual-rate sbr
1589b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
1590b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
1591b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
1592b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case -1:
1593b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable both modes -> the codec will decide which mode should be used
1594b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
1595b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
1596b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
1597b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        default:
1598b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // unsupported sbr mode
1599b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            return BAD_VALUE;
1600b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        }
1601b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi
16025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
16045778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
16055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
16075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
16085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
16115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_AUDIO_PARAM_AACPROFILETYPE profile;
1614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&profile);
1615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nPortIndex = kPortIndexInput;
1616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
16175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
1618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
1619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nChannels = numChannels;
1625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nSampleRate = sampleRate;
1626ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1627ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    profile.eAACStreamFormat =
1628ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        isADTS
1629ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            ? OMX_AUDIO_AACStreamFormatMP4ADTS
1630ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            : OMX_AUDIO_AACStreamFormatMP4FF;
1631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
16325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
1633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
16345778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
163697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryustatus_t ACodec::setupAC3Codec(
163797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        bool encoder, int32_t numChannels, int32_t sampleRate) {
163897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    status_t err = setupRawAudioFormat(
163997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
164097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
164197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
164297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
164397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
164497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
164597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (encoder) {
164697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        ALOGW("AC3 encoding is not supported.");
164797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return INVALID_OPERATION;
164897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
164997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
165097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    OMX_AUDIO_PARAM_ANDROID_AC3TYPE def;
165197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    InitOMXParams(&def);
165297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nPortIndex = kPortIndexInput;
165397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
165497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    err = mOMX->getParameter(
165597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
165697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
165797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
165897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
165997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
166097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
166197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
166297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
166397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
166497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nChannels = numChannels;
166597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nSampleRate = sampleRate;
166697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
166797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    return mOMX->setParameter(
166897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
166997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
167097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
167197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
167297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu}
167397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
16745778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
16755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        bool isAMRWB, int32_t bps) {
16765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (isAMRWB) {
16775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 6600) {
16785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB0;
16795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 8850) {
16805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB1;
16815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 12650) {
16825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB2;
16835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 14250) {
16845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB3;
16855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 15850) {
16865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB4;
16875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 18250) {
16885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB5;
16895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 19850) {
16905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB6;
16915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 23050) {
16925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB7;
16935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 23850 bps
16965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeWB8;
16975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {  // AMRNB
16985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 4750) {
16995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB0;
17005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5150) {
17015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB1;
17025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5900) {
17035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB2;
17045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 6700) {
17055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB3;
17065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7400) {
17075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB4;
17085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7950) {
17095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB5;
17105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 10200) {
17115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB6;
17125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 12200 bps
17155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeNB7;
17165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
17195778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
1720729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_AMRTYPE def;
1721729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
17225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
1723729de186450f78c099637e1fce743fe531862c52Andreas Huber
1724729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err =
1725729de186450f78c099637e1fce743fe531862c52Andreas Huber        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1726729de186450f78c099637e1fce743fe531862c52Andreas Huber
1727729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1728729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1729729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1730729de186450f78c099637e1fce743fe531862c52Andreas Huber
1731729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
17325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
17335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
17355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1736729de186450f78c099637e1fce743fe531862c52Andreas Huber
17375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
17385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
17395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1740729de186450f78c099637e1fce743fe531862c52Andreas Huber
17415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupRawAudioFormat(
17425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
17435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            isWAMR ? 16000 : 8000 /* sampleRate */,
17445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            1 /* numChannels */);
1745729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1746729de186450f78c099637e1fce743fe531862c52Andreas Huber
17475778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupG711Codec(bool encoder, int32_t numChannels) {
17485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(!encoder);  // XXX TODO
17495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1750729de186450f78c099637e1fce743fe531862c52Andreas Huber    return setupRawAudioFormat(
1751729de186450f78c099637e1fce743fe531862c52Andreas Huber            kPortIndexInput, 8000 /* sampleRate */, numChannels);
1752729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1753729de186450f78c099637e1fce743fe531862c52Andreas Huber
17542f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivistatus_t ACodec::setupFlacCodec(
17552f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
17562f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
17572f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder) {
17582f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        OMX_AUDIO_PARAM_FLACTYPE def;
17592f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        InitOMXParams(&def);
17602f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nPortIndex = kPortIndexOutput;
17612f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
17622f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        // configure compression level
17632f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        status_t err = mOMX->getParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
17642f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
17652f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
17662f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
17672f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
17682f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nCompressionLevel = compressionLevel;
17692f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        err = mOMX->setParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
17702f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
17712f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
17722f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
17732f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
17742f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
17752f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
17762f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    return setupRawAudioFormat(
17772f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            encoder ? kPortIndexInput : kPortIndexOutput,
17782f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            sampleRate,
17792f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            numChannels);
17802f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi}
17812f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
1782729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t ACodec::setupRawAudioFormat(
1783729de186450f78c099637e1fce743fe531862c52Andreas Huber        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
1784729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1785729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
1786729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.nPortIndex = portIndex;
1787729de186450f78c099637e1fce743fe531862c52Andreas Huber
1788729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err = mOMX->getParameter(
1789729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1790729de186450f78c099637e1fce743fe531862c52Andreas Huber
1791729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1792729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1793729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1794729de186450f78c099637e1fce743fe531862c52Andreas Huber
1795729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
1796729de186450f78c099637e1fce743fe531862c52Andreas Huber
1797729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->setParameter(
1798729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1799729de186450f78c099637e1fce743fe531862c52Andreas Huber
1800729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1801729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1802729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1803729de186450f78c099637e1fce743fe531862c52Andreas Huber
1804729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
1805729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&pcmParams);
1806729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nPortIndex = portIndex;
1807729de186450f78c099637e1fce743fe531862c52Andreas Huber
1808729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->getParameter(
1809729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1810729de186450f78c099637e1fce743fe531862c52Andreas Huber
1811729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1812729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1813729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1814729de186450f78c099637e1fce743fe531862c52Andreas Huber
1815729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nChannels = numChannels;
1816729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.eNumData = OMX_NumericalDataSigned;
1817729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.bInterleaved = OMX_TRUE;
1818729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nBitPerSample = 16;
1819729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nSamplingRate = sampleRate;
1820729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
1821729de186450f78c099637e1fce743fe531862c52Andreas Huber
1822c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber    if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
1823c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber        return OMX_ErrorNone;
1824729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1825729de186450f78c099637e1fce743fe531862c52Andreas Huber
1826729de186450f78c099637e1fce743fe531862c52Andreas Huber    return mOMX->setParameter(
1827729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1828729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1829729de186450f78c099637e1fce743fe531862c52Andreas Huber
1830f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoPortFormatType(
1831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
1832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_VIDEO_CODINGTYPE compressionFormat,
1833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_COLOR_FORMATTYPE colorFormat) {
1834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
1836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = portIndex;
1837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
1838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool found = false;
1839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1840f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 index = 0;
1841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (;;) {
1842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        format.nIndex = index;
1843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->getParameter(
1844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamVideoPortFormat,
1845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &format, sizeof(format));
1846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
1848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return err;
1849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1850f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The following assertion is violated by TI's video decoder.
1852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // CHECK_EQ(format.nIndex, index);
1853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
1855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexInput
1856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && colorFormat == format.eColorFormat) {
1857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eCompressionFormat does not seem right.
1858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
1859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
1860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexOutput
1862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && compressionFormat == format.eCompressionFormat) {
1863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eColorFormat does not seem right.
1864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
1865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
1866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (format.eCompressionFormat == compressionFormat
1870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && format.eColorFormat == colorFormat) {
1871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            found = true;
1872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ++index;
1876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!found) {
1879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return UNKNOWN_ERROR;
1880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->setParameter(
1883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
1887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1889f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setSupportedOutputFormat() {
1890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
1892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = kPortIndexOutput;
1893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
1894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
1899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)format.eCompressionFormat, (int)OMX_VIDEO_CodingUnused);
1900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mOMX->setParameter(
1902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1906e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic const struct VideoCodingMapEntry {
1907e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    const char *mMime;
1908e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    OMX_VIDEO_CODINGTYPE mVideoCodingType;
1909e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber} kVideoCodingMapEntry[] = {
1910e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC },
19112472b1c0d63454e5d90a982bd6c555de6c3127bdRachad    { MEDIA_MIMETYPE_VIDEO_HEVC, OMX_VIDEO_CodingHEVC },
1912e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 },
1913e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 },
1914e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 },
191594705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 },
191694705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 },
1917e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber};
1918e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
19195778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic status_t GetVideoCodingTypeFromMime(
19205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
1921e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
1922e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
1923e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
1924e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) {
1925e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *codingType = kVideoCodingMapEntry[i].mVideoCodingType;
1926e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
1927e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
1928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1930e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    *codingType = OMX_VIDEO_CodingUnused;
1931e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1932e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
1933e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
1934e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1935e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic status_t GetMimeTypeForVideoCoding(
1936e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        OMX_VIDEO_CODINGTYPE codingType, AString *mime) {
1937e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
1938e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
1939e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
1940e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) {
1941e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *mime = kVideoCodingMapEntry[i].mMime;
1942e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
1943e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
1944e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
1945e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1946e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    mime->clear();
1947e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1948e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
19495778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
19505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19515778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoDecoder(
195289869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        const char *mime, const sp<AMessage> &msg) {
195389869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    int32_t width, height;
195489869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    if (!msg->findInt32("width", &width)
195589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            || !msg->findInt32("height", &height)) {
195689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        return INVALID_OPERATION;
195789869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    }
195889869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar
19595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
19605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
19615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
1967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
1968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
197389869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    int32_t tmp;
197489869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    if (msg->findInt32("color-format", &tmp)) {
197589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        OMX_COLOR_FORMATTYPE colorFormat =
197689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            static_cast<OMX_COLOR_FORMATTYPE>(tmp);
197789869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        err = setVideoPortFormatType(
197889869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar                kPortIndexOutput, OMX_VIDEO_CodingUnused, colorFormat);
197989869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        if (err != OK) {
198089869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            ALOGW("[%s] does not support color format %d",
198189869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar                  mComponentName.c_str(), colorFormat);
198289869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            err = setSupportedOutputFormat();
198389869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        }
198489869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    } else {
198589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        err = setSupportedOutputFormat();
198689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    }
1987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
1993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, width, height, compressionFormat);
1994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
2000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
2001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
20095778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) {
20105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
20115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("color-format", &tmp)) {
20125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
20135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_COLOR_FORMATTYPE colorFormat =
20165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        static_cast<OMX_COLOR_FORMATTYPE>(tmp);
20175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setVideoPortFormatType(
20195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
20205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support color format %d",
20235778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str(), colorFormat);
20245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Input port configuration */
20295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
20315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&def);
20325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
20345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexInput;
20365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
20385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
20395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t width, height, bitrate;
20455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("width", &width)
20465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("height", &height)
20475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("bitrate", &bitrate)) {
20485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
20495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
20525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
20535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t stride;
20555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("stride", &stride)) {
20565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        stride = width;
20575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nStride = stride;
20605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t sliceHeight;
20625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("slice-height", &sliceHeight)) {
20635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sliceHeight = height;
20645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nSliceHeight = sliceHeight;
20675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
20695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
20715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
20725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
20735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
20745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
20755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
20772c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        mTimePerFrameUs = (int64_t) (1000000.0f / frameRate);
20785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
20815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
20825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = colorFormat;
20835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
20855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
20865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set input port definition parameters.",
20895778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
20905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Output port configuration */
20955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
20975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
20985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
21045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
21055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support compression format %d",
21085778822d86b0337407514b9372562b86edfa91cdAndreas Huber             mComponentName.c_str(), compressionFormat);
21095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexOutput;
21145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
21165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
21175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
21235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
21245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = 0;
21255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nBitrate = bitrate;
21265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = compressionFormat;
21275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = OMX_COLOR_FormatUnused;
21285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
21305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
21315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set output port definition parameters.",
21345778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
21355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (compressionFormat) {
21405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingMPEG4:
21415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupMPEG4EncoderParameters(msg);
21425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
21435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingH263:
21455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupH263EncoderParameters(msg);
21465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
21475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingAVC:
21495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupAVCEncoderParameters(msg);
21505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
21515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2152c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        case OMX_VIDEO_CodingHEVC:
2153c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            err = setupHEVCEncoderParameters(msg);
2154c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            break;
2155c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
215689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP8:
215789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP9:
215889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            err = setupVPXEncoderParameters(msg);
215989b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            break;
216089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
21615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
21625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
21635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGI("setupVideoEncoder succeeded");
21665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
21685778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
21695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21700dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dongstatus_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) {
21710dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    OMX_VIDEO_PARAM_INTRAREFRESHTYPE params;
21720dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    InitOMXParams(&params);
21730dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.nPortIndex = kPortIndexOutput;
21740dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
21750dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode);
21760dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
21770dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic ||
21780dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
21790dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
21800dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) {
21810dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
21820dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
21830dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nCirMBs = mbs;
21840dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
21850dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
21860dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive ||
21870dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
21880dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
21890dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) {
21900dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
21910dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
21920dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirMBs = mbs;
21930dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
21940dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t ref;
21950dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) {
21960dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
21970dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
21980dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirRef = ref;
21990dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
22000dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
22010dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = mOMX->setParameter(
22020dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            mNode, OMX_IndexParamVideoIntraRefresh,
22030dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            &params, sizeof(params));
22040dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    return err;
22050dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong}
22060dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
22075778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
22085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (iFramesInterval < 0) {
22095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0xFFFFFFFF;
22105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (iFramesInterval == 0) {
22115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0;
22125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_U32 ret = frameRate * iFramesInterval;
22145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(ret > 1);
22155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return ret;
22165778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
22175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
221896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatic OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) {
221996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    int32_t tmp;
222096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    if (!msg->findInt32("bitrate-mode", &tmp)) {
222196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        return OMX_Video_ControlRateVariable;
222296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    }
222396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
222496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp);
222596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber}
222696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
22275778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
22285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
22295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
22305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
22315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
22325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
223496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
223596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
22365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
22375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
22385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
22395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
22405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
22415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
22435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
22465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&mpeg4type);
22475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPortIndex = kPortIndexOutput;
22485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
22505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
22515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nSliceHeaderSpacing = 0;
22575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bSVH = OMX_FALSE;
22585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bGov = OMX_FALSE;
22595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nAllowedPictureTypes =
22615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
22625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
22645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mpeg4type.nPFrames == 0) {
22655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
22665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nBFrames = 0;
22685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nIDCVLCThreshold = 0;
22695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bACPred = OMX_TRUE;
22705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nMaxPacketSize = 256;
22715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nTimeIncRes = 1000;
22725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nHeaderExtension = 0;
22735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bReversibleVLC = OMX_FALSE;
22745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
22765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
22775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
22785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
22795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
22805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
22835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
22855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
22865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
22895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
22905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
22935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
22945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
229996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
23005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
23025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
23035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
23065778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
23075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23085778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
23095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
23105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
23115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
23125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
23135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
231596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
231696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
23175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
23185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
23195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
23205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
23215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
23225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
23245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_H263TYPE h263type;
23275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h263type);
23285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPortIndex = kPortIndexOutput;
23295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
23315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
23325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
23345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
23355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nAllowedPictureTypes =
23385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
23395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
23415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h263type.nPFrames == 0) {
23425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
23435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nBFrames = 0;
23455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
23475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
23485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
23495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
23505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
23515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
23545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
23565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
23575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
23605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
23615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bPLUSPTYPEAllowed = OMX_FALSE;
23645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bForceRoundingTypeToZero = OMX_FALSE;
23655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPictureHeaderRepetition = 0;
23665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nGOBHeaderInterval = 0;
23675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
23695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
23705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
23725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
23735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
237596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
23765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
23785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
23795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
23825778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
23835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23845778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
23855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
23865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
23875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
23885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
23895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
239196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
239296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
23935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
23945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
23955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
23965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
23975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
23985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
24005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24020dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = OK;
24030dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    int32_t intraRefreshMode = 0;
24040dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) {
24050dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode);
24060dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (err != OK) {
24070dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
24080dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong                    err, intraRefreshMode);
24090dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return err;
24100dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
24110dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
24120dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
24135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_AVCTYPE h264type;
24145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h264type);
24155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nPortIndex = kPortIndexOutput;
24165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24170dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    err = mOMX->getParameter(
24185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
24195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
24215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
24225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nAllowedPictureTypes =
24255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
24265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
24285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
24295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
24305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
24315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
24325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
24335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
24355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
24375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
24385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
24395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
24415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
24425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // XXX
24457c25df82dfc8bbedb58608242f0d923a4594bb14James Dong    if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) {
24467c25df82dfc8bbedb58608242f0d923a4594bb14James Dong        ALOGW("Use baseline profile instead of %d for AVC recording",
24477c25df82dfc8bbedb58608242f0d923a4594bb14James Dong            h264type.eProfile);
24485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
24495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
24525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nSliceHeaderSpacing = 0;
24535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bUseHadamard = OMX_TRUE;
24545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefFrames = 1;
24555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nBFrames = 0;
24565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
24575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (h264type.nPFrames == 0) {
24585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
24595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
24605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx10ActiveMinus1 = 0;
24615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx11ActiveMinus1 = 0;
24625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bEntropyCodingCABAC = OMX_FALSE;
24635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bWeightedPPrediction = OMX_FALSE;
24645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bconstIpred = OMX_FALSE;
24655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirect8x8Inference = OMX_FALSE;
24665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirectSpatialTemporal = OMX_FALSE;
24675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nCabacInitIdc = 0;
24685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.nBFrames != 0) {
24715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
24725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableUEP = OMX_FALSE;
24755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableFMO = OMX_FALSE;
24765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableASO = OMX_FALSE;
24775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableRS = OMX_FALSE;
24785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bFrameMBsOnly = OMX_TRUE;
24795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bMBAFF = OMX_FALSE;
24805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
24815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
24835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
24845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
24865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
24875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
248996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return configureBitrate(bitrate, bitrateMode);
24905778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
24915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2492c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachadstatus_t ACodec::setupHEVCEncoderParameters(const sp<AMessage> &msg) {
2493c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    int32_t bitrate, iFrameInterval;
2494c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findInt32("bitrate", &bitrate)
2495c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
2496c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return INVALID_OPERATION;
2497c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2498c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2499c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
2500c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2501c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    float frameRate;
2502c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findFloat("frame-rate", &frameRate)) {
2503c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t tmp;
2504c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("frame-rate", &tmp)) {
2505c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
2506c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
2507c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        frameRate = (float)tmp;
2508c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2509c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2510c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_PARAM_HEVCTYPE hevcType;
2511c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    InitOMXParams(&hevcType);
2512c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    hevcType.nPortIndex = kPortIndexOutput;
2513c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2514c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    status_t err = OK;
2515c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    err = mOMX->getParameter(
2516c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
2517c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
2518c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
2519c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2520c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2521c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    int32_t profile;
2522c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (msg->findInt32("profile", &profile)) {
2523c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t level;
2524c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("level", &level)) {
2525c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
2526c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
2527c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2528c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        err = verifySupportForProfileAndLevel(profile, level);
2529c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (err != OK) {
2530c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return err;
2531c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
2532c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2533c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eProfile = static_cast<OMX_VIDEO_HEVCPROFILETYPE>(profile);
2534c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eLevel = static_cast<OMX_VIDEO_HEVCLEVELTYPE>(level);
2535c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2536c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2537c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    // TODO: Need OMX structure definition for setting iFrameInterval
2538c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2539c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    err = mOMX->setParameter(
2540c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
2541c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
2542c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
2543c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2544c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2545c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    return configureBitrate(bitrate, bitrateMode);
2546c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad}
2547c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
254889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huberstatus_t ACodec::setupVPXEncoderParameters(const sp<AMessage> &msg) {
254989b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    int32_t bitrate;
25504154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    int32_t iFrameInterval = 0;
25514154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    size_t tsLayers = 0;
25524154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE pattern =
25534154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        OMX_VIDEO_VPXTemporalLayerPatternNone;
25544154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    static const uint32_t kVp8LayerRateAlloction
25554154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS]
25564154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS] = {
25574154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        {100, 100, 100},  // 1 layer
25584154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 60, 100, 100},  // 2 layers {60%, 40%}
25594154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 40,  60, 100},  // 3 layers {40%, 20%, 40%}
25604154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    };
256189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    if (!msg->findInt32("bitrate", &bitrate)) {
256289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        return INVALID_OPERATION;
256389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    }
25644154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    msg->findInt32("i-frame-interval", &iFrameInterval);
256589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
256689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
256789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
25684154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    float frameRate;
25694154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (!msg->findFloat("frame-rate", &frameRate)) {
25704154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        int32_t tmp;
25714154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (!msg->findInt32("frame-rate", &tmp)) {
25724154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            return INVALID_OPERATION;
25734154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
25744154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        frameRate = (float)tmp;
25754154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
25764154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
25774154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    AString tsSchema;
25784154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (msg->findString("ts-schema", &tsSchema)) {
25794154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (tsSchema == "webrtc.vp8.1-layer") {
25804154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
25814154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 1;
25824154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else if (tsSchema == "webrtc.vp8.2-layer") {
25834154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
25844154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 2;
25854154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else if (tsSchema == "webrtc.vp8.3-layer") {
25864154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
25874154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 3;
25884154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else {
25894154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            ALOGW("Unsupported ts-schema [%s]", tsSchema.c_str());
25904154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
25914154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
25924154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
25934154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
25944154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    InitOMXParams(&vp8type);
25954154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    vp8type.nPortIndex = kPortIndexOutput;
25964154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    status_t err = mOMX->getParameter(
25974154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
25984154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            &vp8type, sizeof(vp8type));
25994154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
26004154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (err == OK) {
26014154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (iFrameInterval > 0) {
26024154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nKeyFrameInterval = setPFramesSpacing(iFrameInterval, frameRate);
26034154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
26044154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.eTemporalPattern = pattern;
26054154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.nTemporalLayerCount = tsLayers;
26064154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (tsLayers > 0) {
26074154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            for (size_t i = 0; i < OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS; i++) {
26084154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                vp8type.nTemporalLayerBitrateRatio[i] =
26094154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                    kVp8LayerRateAlloction[tsLayers - 1][i];
26104154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            }
26114154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
26124154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (bitrateMode == OMX_Video_ControlRateConstant) {
26134154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMinQuantizer = 2;
26144154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMaxQuantizer = 63;
26154154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
26164154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
26174154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        err = mOMX->setParameter(
26184154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
26194154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                &vp8type, sizeof(vp8type));
26204154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (err != OK) {
26214154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            ALOGW("Extended VP8 parameters set failed: %d", err);
26224154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
26234154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
26244154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
262589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    return configureBitrate(bitrate, bitrateMode);
262689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber}
262789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
26285778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::verifySupportForProfileAndLevel(
26295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t profile, int32_t level) {
26305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
26315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&params);
26325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    params.nPortIndex = kPortIndexOutput;
26335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (params.nProfileIndex = 0;; ++params.nProfileIndex) {
26355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
26365778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode,
26375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                OMX_IndexParamVideoProfileLevelQuerySupported,
26385778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &params,
26395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sizeof(params));
26405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
26425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
26435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
26445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
26465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
26475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (profile == supportedProfile && level <= supportedLevel) {
26495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OK;
26505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
26515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26525778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
26535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
265496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatus_t ACodec::configureBitrate(
265596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) {
26565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
26575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&bitrateType);
26585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
26595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
26615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
26625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
26635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
26655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
26665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
266896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    bitrateType.eControlRate = bitrateMode;
26695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nTargetBitrate = bitrate;
26705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
26725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
26735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
26745778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
26755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26765778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupErrorCorrectionParameters() {
26775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
26785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&errorCorrectionType);
26795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nPortIndex = kPortIndexOutput;
26805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
26825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
26835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
26845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
26865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OK;  // Optional feature. Ignore this failure
26875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableHEC = OMX_FALSE;
26905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableResync = OMX_TRUE;
26915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nResynchMarkerSpacing = 256;
26925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
26935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableRVLC = OMX_FALSE;
26945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
26965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
26975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
26985778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
26995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2700f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoFormatOnPort(
2701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
2702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat) {
2703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
2704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
2705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
2706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
2708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
2710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
2713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
2715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // XXX Need a (much) better heuristic to compute input buffer sizes.
2716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const size_t X = 64 * 1024;
2717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (def.nBufferSize < X) {
2718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.nBufferSize = X;
2719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
2723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameWidth = width;
2725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameHeight = height;
2726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
2728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eCompressionFormat = compressionFormat;
2729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eColorFormat = OMX_COLOR_FormatUnused;
2730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
2733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
2736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2738f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::initNativeWindow() {
2739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL) {
2740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
2741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
2744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2747d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Hubersize_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
2748d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    size_t n = 0;
2749d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2750d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2751d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        const BufferInfo &info = mBuffers[portIndex].itemAt(i);
2752d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2753d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
2754d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            ++n;
2755d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        }
2756d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    }
2757d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2758d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    return n;
2759d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber}
2760d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
27617e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubersize_t ACodec::countBuffersOwnedByNativeWindow() const {
27627e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    size_t n = 0;
27637e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
27647e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
27657e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
27667e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
27677e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
27687e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            ++n;
27697e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        }
27707e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
27717e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
27727e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    return n;
27737e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
27747e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
27757e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubervoid ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
27767e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (mNativeWindow == NULL) {
27777e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        return;
27787e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
27797e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
2780e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    while (countBuffersOwnedByNativeWindow() > mNumUndequeuedBuffers
27817e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            && dequeueBufferFromNativeWindow() != NULL) {
2782c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        // these buffers will be submitted as regular buffers; account for this
2783c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        if (mStoreMetaDataInOutputBuffers && mMetaDataBuffersToSubmit > 0) {
2784c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar            --mMetaDataBuffersToSubmit;
2785c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        }
27867e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
27877e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
27887e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
2789f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs(
2790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
2791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
2793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus != BufferInfo::OWNED_BY_US
2795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
2796609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGV("[%s] Buffer %u on port %u still has status %d",
2797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mComponentName.c_str(),
2798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info->mBufferID, portIndex, info->mStatus);
2799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
2800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2806f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs() {
2807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return allYourBuffersAreBelongToUs(kPortIndexInput)
2808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        && allYourBuffersAreBelongToUs(kPortIndexOutput);
2809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2811f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::deferMessage(const sp<AMessage> &msg) {
2812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool wasEmptyBefore = mDeferredQueue.empty();
2813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.push_back(msg);
2814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2816f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::processDeferredMessages() {
2817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> > queue = mDeferredQueue;
2818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.clear();
2819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> >::iterator it = queue.begin();
2821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while (it != queue.end()) {
2822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        onMessageReceived(*it++);
2823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
282603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar// static
282703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnarvoid ACodec::describeDefaultColorFormat(DescribeColorFormatParams &params) {
282803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    MediaImage &image = params.sMediaImage;
282903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    memset(&image, 0, sizeof(image));
283003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
283103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mType = MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
283203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mNumPlanes = 0;
283303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
283403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    const OMX_COLOR_FORMATTYPE fmt = params.eColorFormat;
283503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    // we need stride and slice-height to be non-zero
283603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    if (params.nStride == 0 || params.nSliceHeight == 0) {
283703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        ALOGW("cannot describe color format 0x%x = %d with stride=%u and sliceHeight=%u",
283803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                fmt, fmt, params.nStride, params.nSliceHeight);
283903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        return;
284003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    }
284103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
284203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mWidth = params.nFrameWidth;
284303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mHeight = params.nFrameHeight;
284403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
284503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    // only supporting YUV420
284603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    if (fmt != OMX_COLOR_FormatYUV420Planar &&
284703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        fmt != OMX_COLOR_FormatYUV420PackedPlanar &&
284803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        fmt != OMX_COLOR_FormatYUV420SemiPlanar &&
284903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        fmt != OMX_COLOR_FormatYUV420PackedSemiPlanar) {
285003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        ALOGW("do not know color format 0x%x = %d", fmt, fmt);
285103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        return;
285203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    }
285303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
285403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    // set-up YUV format
285503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mType = MediaImage::MEDIA_IMAGE_TYPE_YUV;
285603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mNumPlanes = 3;
285703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mBitDepth = 8;
285803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mOffset = 0;
285903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mColInc = 1;
286003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mRowInc = params.nStride;
286103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mHorizSubsampling = 1;
286203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mVertSubsampling = 1;
286303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
286403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    switch (fmt) {
286503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420Planar: // used for YV12
286603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420PackedPlanar:
286703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight;
286803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mColInc = 1;
286903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mRowInc = params.nStride / 2;
287003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mHorizSubsampling = 2;
287103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mVertSubsampling = 2;
287203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
287303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset
287403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    + (params.nStride * params.nSliceHeight / 4);
287503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mColInc = 1;
287603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mRowInc = params.nStride / 2;
287703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mHorizSubsampling = 2;
287803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mVertSubsampling = 2;
287903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            break;
288003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
288103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420SemiPlanar:
288203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            // FIXME: NV21 for sw-encoder, NV12 for decoder and hw-encoder
288303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420PackedSemiPlanar:
288403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            // NV12
288503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight;
288603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mColInc = 2;
288703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mRowInc = params.nStride;
288803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mHorizSubsampling = 2;
288903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mVertSubsampling = 2;
289003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
289103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset + 1;
289203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mColInc = 2;
289303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mRowInc = params.nStride;
289403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mHorizSubsampling = 2;
289503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mVertSubsampling = 2;
289603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            break;
289703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
289803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        default:
289903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            TRESPASS();
290003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    }
290103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar}
290203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
2903e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarstatus_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> &notify) {
2904e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    // TODO: catch errors an return them instead of using CHECK
290531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
290631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    InitOMXParams(&def);
2907e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    def.nPortIndex = portIndex;
290831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
290931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ(mOMX->getParameter(
291031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)),
291131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber             (status_t)OK);
291231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
2913e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ((int)def.eDir,
2914e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            (int)(portIndex == kPortIndexOutput ? OMX_DirOutput : OMX_DirInput));
291531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
291631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    switch (def.eDomain) {
291731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainVideo:
291831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
291931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
2920e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            switch ((int)videoDef->eCompressionFormat) {
2921e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_VIDEO_CodingUnused:
2922e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
2923e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(mIsEncoder ^ (portIndex == kPortIndexOutput));
2924e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
2925e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
2926e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("stride", videoDef->nStride);
2927e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("slice-height", videoDef->nSliceHeight);
2928e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("color-format", videoDef->eColorFormat);
2929e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
293003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
293103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    DescribeColorFormatParams describeParams;
293203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    InitOMXParams(&describeParams);
293303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    describeParams.eColorFormat = videoDef->eColorFormat;
293403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    describeParams.nFrameWidth = videoDef->nFrameWidth;
293503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    describeParams.nFrameHeight = videoDef->nFrameHeight;
293603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    describeParams.nStride = videoDef->nStride;
293703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    describeParams.nSliceHeight = videoDef->nSliceHeight;
293803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
293903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    OMX_INDEXTYPE describeColorFormatIndex;
294003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    if (mOMX->getExtensionIndex(
294103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                            mNode, "OMX.google.android.index.describeColorFormat",
294203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                            &describeColorFormatIndex) ||
294303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                        mOMX->getParameter(
294403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                            mNode, describeColorFormatIndex,
294503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                            &describeParams, sizeof(describeParams))) {
294603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                        describeDefaultColorFormat(describeParams);
294703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    }
294803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
294903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    if (describeParams.sMediaImage.mType != MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN) {
295003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                        notify->setBuffer(
295103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                                "image-data",
295203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                                ABuffer::CreateAsCopy(
295303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                                        &describeParams.sMediaImage,
295403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                                        sizeof(describeParams.sMediaImage)));
295503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    }
295603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
2957e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_CONFIG_RECTTYPE rect;
2958e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&rect);
2959e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    rect.nPortIndex = kPortIndexOutput;
2960e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
2961e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    if (mOMX->getConfig(
2962e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                mNode, OMX_IndexConfigCommonOutputCrop,
2963e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &rect, sizeof(rect)) != OK) {
2964e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nLeft = 0;
2965e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nTop = 0;
2966e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nWidth = videoDef->nFrameWidth;
2967e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nHeight = videoDef->nFrameHeight;
2968e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    }
296931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
2970e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nLeft, 0);
2971e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nTop, 0);
2972e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nWidth, 0u);
2973e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nHeight, 0u);
2974e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_LE(rect.nLeft + rect.nWidth - 1, videoDef->nFrameWidth);
2975e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_LE(rect.nTop + rect.nHeight - 1, videoDef->nFrameHeight);
2976e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2977e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setRect(
2978577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            "crop",
2979577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nLeft,
2980577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nTop,
2981e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                            rect.nLeft + rect.nWidth - 1,
2982e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                            rect.nTop + rect.nHeight - 1);
2983e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
2984e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
2985e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
29864730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
29874730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP8:
29884730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP9:
29894730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                {
29904730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
29914730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    InitOMXParams(&vp8type);
29924730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    vp8type.nPortIndex = kPortIndexOutput;
29934730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    status_t err = mOMX->getParameter(
29944730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            mNode,
29954730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
29964730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            &vp8type,
29974730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            sizeof(vp8type));
29984730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
29994730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    if (err == OK) {
30004730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        AString tsSchema = "none";
30014730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        if (vp8type.eTemporalPattern
30024730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                == OMX_VIDEO_VPXTemporalLayerPatternWebRTC) {
30034730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            switch (vp8type.nTemporalLayerCount) {
30044730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 1:
30054730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
30064730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.1-layer";
30074730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
30084730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
30094730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 2:
30104730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
30114730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.2-layer";
30124730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
30134730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
30144730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 3:
30154730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
30164730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.3-layer";
30174730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
30184730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
30194730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                default:
30204730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
30214730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
30224730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
30234730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            }
30244730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        }
30254730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        notify->setString("ts-schema", tsSchema);
30264730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    }
30274730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    // Fall through to set up mime.
30284730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                }
30294730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
3030e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                default:
3031e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3032e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(mIsEncoder ^ (portIndex == kPortIndexInput));
3033e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    AString mime;
3034e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    if (GetMimeTypeForVideoCoding(
3035e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        videoDef->eCompressionFormat, &mime) != OK) {
3036e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", "application/octet-stream");
3037e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    } else {
3038e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", mime.c_str());
3039e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    }
3040e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3041e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
304231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            }
3043e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3044e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("width", videoDef->nFrameWidth);
3045e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("height", videoDef->nFrameHeight);
304631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
304731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
304831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
304931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainAudio:
305031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
305131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
305231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
305397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            switch ((int)audioDef->eEncoding) {
3054e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingPCM:
3055e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3056e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_PCMMODETYPE params;
3057e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3058e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3059e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3060e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3061e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioPcm,
3062e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3063e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3064e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
306514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_GT(params.nChannels, 0);
3066e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK(params.nChannels == 1 || params.bInterleaved);
3067e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(params.nBitPerSample, 16u);
306814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
306914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.eNumData,
307014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_NumericalDataSigned);
307114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
307214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.ePCMMode,
307314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_AUDIO_PCMModeLinear);
3074e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3075e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
3076e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
3077e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSamplingRate);
3078e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3079e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mChannelMaskPresent) {
3080e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("channel-mask", mChannelMask);
30818b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                    }
3082e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
30838b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                }
30849806555d3930be43e11106281dee354820ac1c88Andreas Huber
3085e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAAC:
3086e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3087e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AACPROFILETYPE params;
3088e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3089e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3090e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3091e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3092e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAac,
3093e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3094e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3095e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3096e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
3097e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
3098e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
3099e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
3100e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
3101e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3102e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAMR:
3103e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3104e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AMRTYPE params;
3105e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3106e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
31079806555d3930be43e11106281dee354820ac1c88Andreas Huber
3108e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3109e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAmr,
3110e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3111e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3112e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3113e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", 1);
3114e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) {
3115e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
3116e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_WB);
3117e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3118e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 16000);
3119e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    } else {
3120e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
3121e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
3122e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3123e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 8000);
3124e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
3125e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
3126e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
3127e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3128e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingFLAC:
3129e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3130e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_FLACTYPE params;
3131e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3132e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3133e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3134e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3135e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioFlac,
3136e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3137e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3138e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3139e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC);
3140e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
3141e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
3142e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
3143e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
3144e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3145e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingMP3:
3146e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3147e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_MP3TYPE params;
3148e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
3149e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3150e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3151e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_EQ(mOMX->getParameter(
3152e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                mNode, OMX_IndexParamAudioMp3,
3153e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &params, sizeof(params)),
3154e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                             (status_t)OK);
3155e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3156e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MPEG);
3157e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
3158e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
3159e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3160e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
3161e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3162e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingVORBIS:
3163e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3164e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_VORBISTYPE params;
3165e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
3166e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3167e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3168e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_EQ(mOMX->getParameter(
3169e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                mNode, OMX_IndexParamAudioVorbis,
3170e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &params, sizeof(params)),
3171e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                             (status_t)OK);
3172e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3173e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_VORBIS);
3174e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
3175e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
3176e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3177e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
3178e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
317997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                case OMX_AUDIO_CodingAndroidAC3:
318097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                {
318197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    OMX_AUDIO_PARAM_ANDROID_AC3TYPE params;
318297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    InitOMXParams(&params);
3183e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
318497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
318597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    CHECK_EQ((status_t)OK, mOMX->getParameter(
318697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            mNode,
318797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
318897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            &params,
318997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            sizeof(params)));
319097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
319197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AC3);
319297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("channel-count", params.nChannels);
319397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("sample-rate", params.nSampleRate);
319497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    break;
319597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                }
3196e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
31978c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                case OMX_AUDIO_CodingAndroidOPUS:
31988c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                {
31998c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    OMX_AUDIO_PARAM_ANDROID_OPUSTYPE params;
32008c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    InitOMXParams(&params);
32018c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    params.nPortIndex = portIndex;
32028c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
32038c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    CHECK_EQ((status_t)OK, mOMX->getParameter(
32048c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            mNode,
32058c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus,
32068c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            &params,
32078c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            sizeof(params)));
32088c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
32098c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_OPUS);
32108c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("channel-count", params.nChannels);
32118c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("sample-rate", params.nSampleRate);
32128c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    break;
32138c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                }
32148c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
3215e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                default:
3216e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    ALOGE("UNKNOWN AUDIO CODING: %d\n", audioDef->eEncoding);
3217e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    TRESPASS();
3218e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
321931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
322031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
322131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
322231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        default:
322331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            TRESPASS();
322431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    }
322531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3226e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    return OK;
3227e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar}
3228e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3229e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarvoid ACodec::sendFormatChange(const sp<AMessage> &reply) {
3230e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    sp<AMessage> notify = mNotify->dup();
3231e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    notify->setInt32("what", kWhatOutputFormatChanged);
3232e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3233e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ(getPortFormat(kPortIndexOutput, notify), (status_t)OK);
3234e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3235e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    AString mime;
3236e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK(notify->findString("mime", &mime));
3237e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3238e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    int32_t left, top, right, bottom;
3239e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if (mime == MEDIA_MIMETYPE_VIDEO_RAW &&
3240e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        mNativeWindow != NULL &&
3241e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->findRect("crop", &left, &top, &right, &bottom)) {
3242e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        // notify renderer of the crop change
3243e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        // NOTE: native window uses extended right-bottom coordinate
3244e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        reply->setRect("crop", left, top, right + 1, bottom + 1);
3245e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    } else if (mime == MEDIA_MIMETYPE_AUDIO_RAW &&
3246e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar               (mEncoderDelay || mEncoderPadding)) {
3247e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        int32_t channelCount;
3248e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        CHECK(notify->findInt32("channel-count", &channelCount));
3249e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        size_t frameSize = channelCount * sizeof(int16_t);
3250e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        if (mSkipCutBuffer != NULL) {
3251e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            size_t prevbufsize = mSkipCutBuffer->size();
3252e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            if (prevbufsize != 0) {
3253e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                ALOGW("Replacing SkipCutBuffer holding %d "
3254e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                      "bytes",
3255e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                      prevbufsize);
3256e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            }
3257e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        }
3258e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        mSkipCutBuffer = new SkipCutBuffer(
3259e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                mEncoderDelay * frameSize,
3260e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                mEncoderPadding * frameSize);
3261e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
3262e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
326331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->post();
326431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
326531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mSentFormat = true;
326631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber}
326731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
32685778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
3269cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    sp<AMessage> notify = mNotify->dup();
3270d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatError);
3271251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    ALOGE("signalError(omxError %#x, internalError %d)", error, internalError);
3272251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
3273251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (internalError == UNKNOWN_ERROR) { // find better error code
3274251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        const status_t omxStatus = statusFromOMXError(error);
3275251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        if (omxStatus != 0) {
3276251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            internalError = omxStatus;
3277251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        } else {
3278251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            ALOGW("Invalid OMX error %#x", error);
3279251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        }
3280251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
32815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("err", internalError);
3282251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    notify->setInt32("actionCode", ACTION_CODE_FATAL); // could translate from OMX error.
3283cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->post();
3284cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber}
3285cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber
3286bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huberstatus_t ACodec::pushBlankBuffersToNativeWindow() {
3287bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    status_t err = NO_ERROR;
3288bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    ANativeWindowBuffer* anb = NULL;
3289bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int numBufs = 0;
3290bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int minUndequeuedBufs = 0;
3291bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3292bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We need to reconnect to the ANativeWindow as a CPU client to ensure that
3293bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // no frames get dropped by SurfaceFlinger assuming that these are video
3294bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // frames.
3295bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_disconnect(mNativeWindow.get(),
3296bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_MEDIA);
3297bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3298bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
3299bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3300bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
3301bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3302bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3303bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_connect(mNativeWindow.get(),
3304bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_CPU);
3305bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3306bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
3307bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3308bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
3309bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3310bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3311bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffers_geometry(mNativeWindow.get(), 1, 1,
3312bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            HAL_PIXEL_FORMAT_RGBX_8888);
3313bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3314bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffers_geometry failed: %s (%d)",
3315bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3316bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
3317bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3318bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
331987eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin    err = native_window_set_scaling_mode(mNativeWindow.get(),
332087eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
332187eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin    if (err != NO_ERROR) {
332287eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin        ALOGE("error pushing blank_frames: set_scaling_mode failed: %s (%d)",
332387eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin              strerror(-err), -err);
332487eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin        goto error;
3325bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3326bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3327bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_usage(mNativeWindow.get(),
3328bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            GRALLOC_USAGE_SW_WRITE_OFTEN);
3329bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3330bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_usage failed: %s (%d)",
3331bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3332bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
3333bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3334bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3335bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = mNativeWindow->query(mNativeWindow.get(),
3336bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs);
3337bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3338bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: MIN_UNDEQUEUED_BUFFERS query "
3339bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                "failed: %s (%d)", strerror(-err), -err);
3340bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
3341bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3342bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3343bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    numBufs = minUndequeuedBufs + 1;
3344bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffer_count(mNativeWindow.get(), numBufs);
3345bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3346bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffer_count failed: %s (%d)",
3347bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3348bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
3349bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3350bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3351bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We  push numBufs + 1 buffers to ensure that we've drawn into the same
3352bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // buffer twice.  This should guarantee that the buffer has been displayed
3353bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // on the screen and then been replaced, so an previous video frames are
3354bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // guaranteed NOT to be currently displayed.
3355bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    for (int i = 0; i < numBufs + 1; i++) {
33561e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        int fenceFd = -1;
33571e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &anb);
3358bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3359bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: dequeueBuffer failed: %s (%d)",
3360bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3361bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
3362bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3363bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3364bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
3365bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3366bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Fill the buffer with the a 1x1 checkerboard pattern ;)
3367bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        uint32_t* img = NULL;
3368bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
3369bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3370bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: lock failed: %s (%d)",
3371bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3372bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
3373bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3374bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3375bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        *img = 0;
3376bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3377bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->unlock();
3378bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3379bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: unlock failed: %s (%d)",
3380bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3381bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
3382bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3383bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3384bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->queueBuffer(mNativeWindow.get(),
33851e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                buf->getNativeBuffer(), -1);
3386bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3387bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: queueBuffer failed: %s (%d)",
3388bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3389bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
3390bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3391bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3392bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        anb = NULL;
3393bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3394bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3395bc098410be55f9d96f394b3981a0c482b83859b6Andreas Hubererror:
3396bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3397bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3398bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after an error.
3399bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (anb != NULL) {
34001e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis            mNativeWindow->cancelBuffer(mNativeWindow.get(), anb, -1);
3401bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3402bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3403bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_disconnect(mNativeWindow.get(),
3404bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
3405bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_connect(mNativeWindow.get(),
3406bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
3407bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3408bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
3409bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    } else {
3410bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after success.
3411bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_disconnect(mNativeWindow.get(),
3412bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
3413bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3414bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
3415bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3416bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
3417bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3418bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3419bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_connect(mNativeWindow.get(),
3420bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
3421bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3422bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
3423bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3424bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
3425bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3426bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3427bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return NO_ERROR;
3428bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3429bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber}
3430bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3433eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberACodec::PortDescription::PortDescription() {
3434eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3435eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3436496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t ACodec::requestIDRFrame() {
3437496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    if (!mIsEncoder) {
3438496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        return ERROR_UNSUPPORTED;
3439496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    }
3440496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
3441496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    OMX_CONFIG_INTRAREFRESHVOPTYPE params;
3442496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    InitOMXParams(&params);
3443496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
3444496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.nPortIndex = kPortIndexOutput;
3445496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.IntraRefreshVOP = OMX_TRUE;
3446496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
3447496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    return mOMX->setConfig(
3448496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            mNode,
3449496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            OMX_IndexConfigVideoIntraVOPRefresh,
3450496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            &params,
3451496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            sizeof(params));
3452496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
3453496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
3454eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubervoid ACodec::PortDescription::addBuffer(
3455eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        IOMX::buffer_id id, const sp<ABuffer> &buffer) {
3456eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBufferIDs.push_back(id);
3457eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBuffers.push_back(buffer);
3458eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3459eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3460eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersize_t ACodec::PortDescription::countBuffers() {
3461eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.size();
3462eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3463eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3464eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberIOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const {
3465eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.itemAt(index);
3466eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3467eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3468eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const {
3469eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBuffers.itemAt(index);
3470eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3471eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3472eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber////////////////////////////////////////////////////////////////////////////////
3473eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3474f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
3475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : AState(parentState),
3476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mCodec(codec) {
3477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3479ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas HuberACodec::BaseState::PortMode ACodec::BaseState::getPortMode(
3480ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
3481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return KEEP_BUFFERS;
3482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3484f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
3485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatInputBufferFilled:
3487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onInputBufferFilled(msg);
3489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatOutputBufferDrained:
3493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onOutputBufferDrained(msg);
3495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatOMXMessage:
3499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXMessage(msg);
3501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
35037cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
35047cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
35057cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
3506251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            // This may result in an app illegal state exception.
35077cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            ALOGE("Message 0x%x was not handled", msg->what());
35087cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
35097cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            return true;
35107cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
35117cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
3512ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        case ACodec::kWhatOMXDied:
3513ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        {
3514251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            // This will result in kFlagSawMediaServerDie handling in MediaCodec.
3515ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            ALOGE("OMX/mediaserver died, signalling error!");
3516ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT);
3517ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            break;
3518ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        }
3519ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
3522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3527f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
3528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t type;
3529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findInt32("type", &type));
3530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
35315e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // there is a possibility that this is an outstanding message for a
35325e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // codec that we have already destroyed
35335e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    if (mCodec->mNode == NULL) {
35345e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar        ALOGI("ignoring message as already freed component: %s",
35355e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar                msg->debugString().c_str());
35365e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar        return true;
35375e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    }
35385e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar
3539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::node_id nodeID;
3540609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("node", (int32_t*)&nodeID));
3541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(nodeID, mCodec->mNode);
3542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (type) {
3544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EVENT:
3545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t event, data1, data2;
3547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("event", &event));
3548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data1", &data1));
3549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data2", &data2));
3550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
35510af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            if (event == OMX_EventCmdComplete
35520af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data1 == OMX_CommandFlush
35530af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data2 == (int32_t)OMX_ALL) {
35540af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // Use of this notification is not consistent across
35550af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // implementations. We'll drop this notification and rely
35560af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // on flush-complete notifications on the individual port
35570af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // indices instead.
35580af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
35590af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                return true;
35600af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            }
35610af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
3562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEvent(
3563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_EVENTTYPE>(event),
3564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data1),
3565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data2));
3566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EMPTY_BUFFER_DONE:
3569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
3571609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
3572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEmptyBufferDone(bufferID);
3574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::FILL_BUFFER_DONE:
3577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
3579609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
3580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t rangeOffset, rangeLength, flags;
3582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs;
3583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_offset", &rangeOffset));
3585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_length", &rangeLength));
3586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("flags", &flags));
3587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt64("timestamp", &timeUs));
3588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXFillBufferDone(
3590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    bufferID,
3591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (size_t)rangeOffset, (size_t)rangeLength,
3592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (OMX_U32)flags,
3593784e24e386b088c05d653ab482f2e95cb53e3d01Andy Hung                    timeUs);
3594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
3598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3602f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEvent(
3603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (event != OMX_EventError) {
36053856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] EVENT(%d, 0x%08lx, 0x%08lx)",
3606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mCodec->mComponentName.c_str(), event, data1, data2);
3607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return false;
3609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
361129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block    ALOGE("[%s] ERROR(0x%08lx)", mCodec->mComponentName.c_str(), data1);
3612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3613251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // verify OMX component sends back an error we expect.
3614251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    OMX_ERRORTYPE omxError = (OMX_ERRORTYPE)data1;
3615251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (!isOMXError(omxError)) {
3616251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        ALOGW("Invalid OMX error %#x", omxError);
3617251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        omxError = OMX_ErrorUndefined;
3618251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
3619251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    mCodec->signalError(omxError);
3620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3624f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID) {
36253856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] onOMXEmptyBufferDone %p",
3626349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber         mCodec->mComponentName.c_str(), bufferID);
3627349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexInput, bufferID);
3630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
3632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3634d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    const sp<AMessage> &bufferMeta = info->mData->meta();
3635d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    void *mediaBuffer;
3636d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (bufferMeta->findPointer("mediaBuffer", &mediaBuffer)
3637d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && mediaBuffer != NULL) {
3638d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // We're in "store-metadata-in-buffers" mode, the underlying
3639d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // OMX component had access to data that's implicitly refcounted
3640d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // by this "mediaBuffer" object. Now that the OMX component has
3641d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // told us that it's done with the input buffer, we can decrement
3642d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // the mediaBuffer's reference count.
364396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
364496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        ALOGV("releasing mbuf %p", mediaBuffer);
364596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
3646d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ((MediaBuffer *)mediaBuffer)->release();
3647d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mediaBuffer = NULL;
3648d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3649d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        bufferMeta->setPointer("mediaBuffer", NULL);
3650d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
3651d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
3653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            postFillThisBuffer(info);
3660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();  // Not currently used
3666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3673f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
3674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
3675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
3679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
3681d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatFillThisBuffer);
3682609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    notify->setInt32("buffer-id", info->mBufferID);
3683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mData->meta()->clear();
36852d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    notify->setBuffer("buffer", info->mData);
3686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec->id());
3688609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    reply->setInt32("buffer-id", info->mBufferID);
3689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setMessage("reply", reply);
3691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->post();
3693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
3695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3697f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
3698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
3699609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
37002d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    sp<ABuffer> buffer;
3701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t err = OK;
37025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool eos = false;
3703a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar    PortMode mode = getPortMode(kPortIndexInput);
37045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37052d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    if (!msg->findBuffer("buffer", &buffer)) {
3706a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar        /* these are unfilled buffers returned by client */
3707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findInt32("err", &err));
3708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
37097fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        if (err == OK) {
37107fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            /* buffers with no errors are returned on MediaCodec.flush */
37117fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            mode = KEEP_BUFFERS;
37127fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        } else {
37137fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            ALOGV("[%s] saw error %d instead of an input buffer",
37147fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                 mCodec->mComponentName.c_str(), err);
37157fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            eos = true;
37167fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        }
37173831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
37182d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber        buffer.clear();
3719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
37215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
37225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
37235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
37245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = ERROR_END_OF_STREAM;
37255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
37265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
3728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_UPSTREAM);
3729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
37355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (eos) {
3736dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (!mCodec->mPortEOS[kPortIndexInput]) {
3737dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
3738dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mInputEOSResult = err;
3739dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
3740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
37465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
3747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int64_t timeUs;
3748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
3749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
3751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t isCSD;
3753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
3754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
3755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
37575778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (eos) {
37585778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    flags |= OMX_BUFFERFLAG_EOS;
37595778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
37605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer != info->mData) {
3762d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGV("[%s] Needs to copy input data for buffer %p. (%p != %p)",
3763d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(),
3764d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         bufferID,
3765d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         buffer.get(), info->mData.get());
3766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    CHECK_LE(buffer->size(), info->mData->capacity());
3768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    memcpy(info->mData->data(), buffer->data(), buffer->size());
3769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3771078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
37723856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ codec specific data",
3773078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID);
37745778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else if (flags & OMX_BUFFERFLAG_EOS) {
37755778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] calling emptyBuffer %p w/ EOS",
37765778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str(), bufferID);
3777078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                } else {
3778d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3779d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGI("[%s] calling emptyBuffer %p w/ time %lld us",
3780d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
3781d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#else
37823856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ time %lld us",
3783078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
3784d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3785078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                }
3786349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3787d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3788d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ACodec::BufferStats stats;
3789d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
3790d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mFillBufferDoneTimeUs = -1ll;
3791d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mCodec->mBufferStats.add(timeUs, stats);
3792d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3793d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3794054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                if (mCodec->mStoreMetaDataInOutputBuffers) {
3795054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    // try to submit an output buffer for each input buffer
3796054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    PortMode outputMode = getPortMode(kPortIndexOutput);
3797054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3798054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    ALOGV("MetaDataBuffersToSubmit=%u portMode=%s",
3799054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            mCodec->mMetaDataBuffersToSubmit,
3800054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            (outputMode == FREE_BUFFERS ? "FREE" :
3801054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                             outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
3802054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    if (outputMode == RESUBMIT_BUFFERS) {
3803054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                        CHECK_EQ(mCodec->submitOutputMetaDataBuffer(),
3804054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                                (status_t)OK);
3805054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    }
3806054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                }
3807054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
3809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
3810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
3811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            buffer->size(),
3813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            flags,
3814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            timeUs),
3815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
3816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
38195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (!eos) {
38205778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    getMoreInputDataIfPossible();
38215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
38225778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] Signalled EOS on the input port",
38235778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str());
38245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38255778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
38265778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mInputEOSResult = err;
38275778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
3828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
3829dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (err != ERROR_END_OF_STREAM) {
38303856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port "
3831dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         "due to error %d",
3832dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str(), err);
3833dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                } else {
38343856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port",
3835dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str());
3836dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
3837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
38383856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] calling emptyBuffer %p signalling EOS",
3839349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                     mCodec->mComponentName.c_str(), bufferID);
3840349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
3842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
3843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
3844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_BUFFERFLAG_EOS,
3847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0),
3848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
3849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3850f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexInput] = true;
3853dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                mCodec->mInputEOSResult = err;
3854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3857625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih
3858625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih        default:
3859625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3860625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih            break;
3861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3864f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::getMoreInputDataIfPossible() {
3865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
3866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *eligible = NULL;
3870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
3872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
3873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
3875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
3876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // There's already a "read" pending.
3877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
3878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
3880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_US) {
3882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            eligible = info;
3883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (eligible == NULL) {
3887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(eligible);
3891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3893f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXFillBufferDone(
3894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferID,
3895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        size_t rangeOffset, size_t rangeLength,
3896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 flags,
3897784e24e386b088c05d653ab482f2e95cb53e3d01Andy Hung        int64_t timeUs) {
3898609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] onOMXFillBufferDone %u time %" PRId64 " us, flags = 0x%08x",
38995778822d86b0337407514b9372562b86edfa91cdAndreas Huber         mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
3900349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
3902d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3903d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3904d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    index = mCodec->mBufferStats.indexOfKey(timeUs);
3905d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (index >= 0) {
3906d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
3907d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
3908d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3909d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ALOGI("frame PTS %lld: %lld",
3910d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                timeUs,
3911d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
3912d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3913d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mCodec->mBufferStats.removeItemsAt(index);
3914d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats = NULL;
3915d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
3916d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3917d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
3920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
3922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3923054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mDequeuedAt = ++mCodec->mDequeueCounter;
3924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
3927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
39345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (rangeLength == 0 && !(flags & OMX_BUFFERFLAG_EOS)) {
3935609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                ALOGV("[%s] calling fillBuffer %u",
39365778822d86b0337407514b9372562b86edfa91cdAndreas Huber                     mCodec->mComponentName.c_str(), info->mBufferID);
3937349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
39385778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK_EQ(mCodec->mOMX->fillBuffer(
39395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mCodec->mNode, info->mBufferID),
39405778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         (status_t)OK);
3941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
39425778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
39435778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
39445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
394531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3946577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            sp<AMessage> reply =
3947577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                new AMessage(kWhatOutputBufferDrained, mCodec->id());
3948577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
39494bdda35319d5f46efea2089b865c8a64816389cdMarco Nelissen            if (!mCodec->mSentFormat && rangeLength > 0) {
3950577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->sendFormatChange(reply);
39515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
3952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3953308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            if (mCodec->mUseMetadataOnEncoderOutput) {
3954308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                native_handle_t* handle =
3955308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        *(native_handle_t**)(info->mData->data() + 4);
3956308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setPointer("handle", handle);
3957308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeOffset", rangeOffset);
3958308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeLength", rangeLength);
3959308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            } else {
3960308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->setRange(rangeOffset, rangeLength);
3961308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            }
3962496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#if 0
396321ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen            if (mCodec->mNativeWindow == NULL) {
3964496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                if (IsIDR(info->mData)) {
3965496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                    ALOGI("IDR frame");
3966496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                }
39675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
396821ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen#endif
3969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
39708b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            if (mCodec->mSkipCutBuffer != NULL) {
39718b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                mCodec->mSkipCutBuffer->submit(info->mData);
39728b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            }
39735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mData->meta()->setInt64("timeUs", timeUs);
3974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
39755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3976d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatDrainThisBuffer);
3977609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            notify->setInt32("buffer-id", info->mBufferID);
39782d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            notify->setBuffer("buffer", info->mData);
39795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("flags", flags);
3980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3981609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            reply->setInt32("buffer-id", info->mBufferID);
3982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
39835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setMessage("reply", reply);
3984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
39855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->post();
39865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
3988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (flags & OMX_BUFFERFLAG_EOS) {
39905778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
39915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                sp<AMessage> notify = mCodec->mNotify->dup();
3993d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar                notify->setInt32("what", CodecBase::kWhatEOS);
3994dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                notify->setInt32("err", mCodec->mInputEOSResult);
3995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->post();
3996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexOutput] = true;
3998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
4005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
4007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
4008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4015f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
4016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
4017609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
4018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
4019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
4020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
4021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM);
4022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4023577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    android_native_rect_t crop;
4024577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    if (msg->findRect("crop",
4025577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            &crop.left, &crop.top, &crop.right, &crop.bottom)) {
4026577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar        CHECK_EQ(0, native_window_set_crop(
4027577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->mNativeWindow.get(), &crop));
4028577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    }
4029577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
4030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t render;
4031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mNativeWindow != NULL
40326aade6058521b0dbd35a9a4620f4d04f02f90444Marco Nelissen            && msg->findInt32("render", &render) && render != 0
403379ee2399b67c7a11042c5904dc1309712a76f8cbJianzheng Zhou            && info->mData != NULL && info->mData->size() != 0) {
40346fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        ATRACE_NAME("render");
4035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The client wants this buffer to be rendered.
4036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4037fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        int64_t timestampNs = 0;
4038fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        if (!msg->findInt64("timestampNs", &timestampNs)) {
4039fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // TODO: it seems like we should use the timestamp
4040fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // in the (media)buffer as it potentially came from
4041fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // an input surface, but we did not propagate it prior to
4042fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // API 20.  Perhaps check for target SDK version.
4043fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#if 0
4044fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            if (info->mData->meta()->findInt64("timeUs", &timestampNs)) {
404547aea1f7c58f5302b16822f9e7e1763f2af04ef5Lajos Molnar                ALOGV("using buffer PTS of %" PRId64, timestampNs);
4046fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar                timestampNs *= 1000;
4047fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            }
4048fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#endif
4049fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
4050fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
40515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err;
4052fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        err = native_window_set_buffers_timestamp(mCodec->mNativeWindow.get(), timestampNs);
4053fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        if (err != OK) {
4054fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            ALOGW("failed to set buffer timestamp: %d", err);
4055fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
4056fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
40575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if ((err = mCodec->mNativeWindow->queueBuffer(
4058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNativeWindow.get(),
40591e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                    info->mGraphicBuffer.get(), -1)) == OK) {
4060cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
4061cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        } else {
4062251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
4063cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
4064cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        }
4065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
40666fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        if (mCodec->mNativeWindow != NULL &&
40676fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar            (info->mData == NULL || info->mData->size() != 0)) {
40686fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar            ATRACE_NAME("frame-drop");
40696fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        }
4070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_US;
4071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
4074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
4079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4081f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // We cannot resubmit the buffer we just rendered, dequeue
4082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // the spare instead.
4083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info = mCodec->dequeueBufferFromNativeWindow();
4085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4086f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4089f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (!mCodec->mPortEOS[kPortIndexOutput]) {
4092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // We cannot resubmit the buffer we just rendered, dequeue
4094f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // the spare instead.
4095f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info = mCodec->dequeueBufferFromNativeWindow();
4097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
4098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4099c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                if (info != NULL) {
4100609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                    ALOGV("[%s] calling fillBuffer %u",
4101c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                         mCodec->mComponentName.c_str(), info->mBufferID);
4102349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4103c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
4104c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                             (status_t)OK);
4105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4106c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4107c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                }
4108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
4115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
4117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
4118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4125f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::UninitializedState::UninitializedState(ACodec *codec)
4126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4129c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::UninitializedState::stateEntered() {
4130c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("Now uninitialized");
4131ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4132ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (mDeathNotifier != NULL) {
4133ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mCodec->mOMX->asBinder()->unlinkToDeath(mDeathNotifier);
4134ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
4135ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
4136ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4137ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNativeWindow.clear();
4138ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNode = NULL;
4139ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mOMX.clear();
4140ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mQuirks = 0;
4141ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mFlags = 0;
4142308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    mCodec->mUseMetadataOnEncoderOutput = 0;
4143ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mComponentName.clear();
4144c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4145c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4146f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
4147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatSetup:
4151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onSetup(msg);
4153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
41585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case ACodec::kWhatAllocateComponent:
41595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
41605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            onAllocateComponent(msg);
41615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            handled = true;
41625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
41635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
41645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatShutdown:
4166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4167c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
4168c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
4169c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
417054b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            ALOGW_IF(keepComponentAllocated,
417154b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar                     "cannot keep component allocated on shutdown in Uninitialized state");
4172c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4174d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
4175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
4176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4178c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
4179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatFlush:
4182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4184d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
4185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
4186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4188c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
4189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
4193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4198f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::UninitializedState::onSetup(
4199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4200c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (onAllocateComponent(msg)
4201c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            && mCodec->mLoadedState->onConfigureComponent(msg)) {
4202c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mLoadedState->onStart();
4203c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
42045778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
42055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4206c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
42075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onAllocateComponent");
42085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4209c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    CHECK(mCodec->mNode == NULL);
42105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMXClient client;
4212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(client.connect(), (status_t)OK);
4213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<IOMX> omx = client.interface();
4215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4216ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec->id());
4217ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4218ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mDeathNotifier = new DeathNotifier(notify);
4219ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (omx->asBinder()->linkToDeath(mDeathNotifier) != OK) {
4220ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // This was a local binder, if it dies so do we, we won't care
4221ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // about any notifications in the afterlife.
4222ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
4223ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
4224ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4225e671207115fac3914134c61b336d5fa0242c68caAndreas Huber    Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs;
42265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    AString mime;
4228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
42295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString componentName;
4230d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint32_t quirks = 0;
42317791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen    int32_t encoder = false;
42325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findString("componentName", &componentName)) {
4233e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        ssize_t index = matchingCodecs.add();
4234e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        OMXCodec::CodecNameAndQuirks *entry = &matchingCodecs.editItemAt(index);
4235e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        entry->mName = String8(componentName.c_str());
4236afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
4237e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        if (!OMXCodec::findCodecQuirks(
4238e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                    componentName.c_str(), &entry->mQuirks)) {
4239e671207115fac3914134c61b336d5fa0242c68caAndreas Huber            entry->mQuirks = 0;
4240afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
42415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
42425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(msg->findString("mime", &mime));
42435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
42445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("encoder", &encoder)) {
42455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder = false;
42465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
42475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
42485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMXCodec::findMatchingCodecs(
42495778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mime.c_str(),
42505778822d86b0337407514b9372562b86edfa91cdAndreas Huber                encoder, // createEncoder
42515778822d86b0337407514b9372562b86edfa91cdAndreas Huber                NULL,  // matchComponentName
42525778822d86b0337407514b9372562b86edfa91cdAndreas Huber                0,     // flags
4253e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                &matchingCodecs);
42545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
42551065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
42561065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    sp<CodecObserver> observer = new CodecObserver;
42571065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    IOMX::node_id node = NULL;
42581065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
42591065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
42601065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            ++matchIndex) {
4261e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        componentName = matchingCodecs.itemAt(matchIndex).mName.string();
4262e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        quirks = matchingCodecs.itemAt(matchIndex).mQuirks;
4263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4264078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        pid_t tid = androidGetTid();
4265078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        int prevPriority = androidGetThreadPriority(tid);
4266078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
42671065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        status_t err = omx->allocateNode(componentName.c_str(), observer, &node);
4268078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, prevPriority);
4269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
42701065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        if (err == OK) {
42711065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            break;
42727a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He        } else {
42737a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He            ALOGW("Allocating component '%s' failed, try next one.", componentName.c_str());
42741065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
42751065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
42761065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        node = NULL;
42771065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    }
42781065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
4279c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    if (node == NULL) {
42805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!mime.empty()) {
42817791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen            ALOGE("Unable to instantiate a %scoder for type '%s'.",
42827791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen                    encoder ? "en" : "de", mime.c_str());
42835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
42847791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen            ALOGE("Unable to instantiate codec '%s'.", componentName.c_str());
42855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
4286c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
4287cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        mCodec->signalError(OMX_ErrorComponentNotFound);
4288c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
4289c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
4290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4291ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    notify = new AMessage(kWhatOMXMessage, mCodec->id());
4292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    observer->setNotificationMessage(notify);
4293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mComponentName = componentName;
4295ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    mCodec->mFlags = 0;
4296ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
4297ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (componentName.endsWith(".secure")) {
4298ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        mCodec->mFlags |= kFlagIsSecure;
42990167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
4300ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
4301ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
4302afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mCodec->mQuirks = quirks;
4303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mOMX = omx;
4304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mNode = node;
4305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
43065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
43075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
4308d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatComponentAllocated);
43095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setString("componentName", mCodec->mComponentName.c_str());
43105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
43115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4312c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4313c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mCodec->changeState(mCodec->mLoadedState);
4314c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4315c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
43165778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
43175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4318c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
4319c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4320c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas HuberACodec::LoadedState::LoadedState(ACodec *codec)
4321c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    : BaseState(codec) {
4322c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4323c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4324c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::stateEntered() {
4325c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
4326c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4327f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mPortEOS[kPortIndexInput] =
4328f6f38287b97ec69b169387add6458f859b770e65Andreas Huber        mCodec->mPortEOS[kPortIndexOutput] = false;
4329f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
4330f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mInputEOSResult = OK;
4331f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
4332054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mDequeueCounter = 0;
4333054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mMetaDataBuffersToSubmit = 0;
4334a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    mCodec->mRepeatFrameDelayUs = -1ll;
4335e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mInputFormat.clear();
4336e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mOutputFormat.clear();
4337054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4338c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (mCodec->mShutdownInProgress) {
4339c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
4340c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4341c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mShutdownInProgress = false;
4342c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mKeepComponentAllocated = false;
4343c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4344c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        onShutdown(keepComponentAllocated);
4345c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
434654b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    mCodec->mExplicitShutdown = false;
4347c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4348c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4349c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
4350c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (!keepComponentAllocated) {
4351c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK);
4352c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4353c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->changeState(mCodec->mUninitializedState);
4354c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
4355c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
435654b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    if (mCodec->mExplicitShutdown) {
435754b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        sp<AMessage> notify = mCodec->mNotify->dup();
4358d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
435954b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        notify->post();
436054b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        mCodec->mExplicitShutdown = false;
436154b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    }
4362c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4363c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4364c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
4365c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool handled = false;
4366c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4367c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    switch (msg->what()) {
4368c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatConfigureComponent:
4369c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
4370c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onConfigureComponent(msg);
4371c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
4372c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
4373c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
4374c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
43757cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
43767cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
43777cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            onCreateInputSurface(msg);
43787cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
43797cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
43807cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
43817cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4382c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatStart:
4383c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
4384c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onStart();
4385c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
4386c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
4387c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
4388c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4389c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatShutdown:
4390c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
4391c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
4392c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
4393c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
4394c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
439554b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
4396c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onShutdown(keepComponentAllocated);
4397c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4398c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
4399c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
4400c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
4401c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4402c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatFlush:
4403c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
4404c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4405d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
4406c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->post();
4407c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4408c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
4409c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
4410c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
4411c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4412c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        default:
4413c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            return BaseState::onMessageReceived(msg);
4414c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
4415c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4416c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return handled;
4417c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4418c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4419c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onConfigureComponent(
44205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg) {
44215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onConfigureComponent");
44225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
44235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(mCodec->mNode != NULL);
44245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
44255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString mime;
44265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findString("mime", &mime));
44275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
44285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mCodec->configureCodec(mime.c_str(), msg);
44295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
44305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
4431c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        ALOGE("[%s] configureCodec returning error %d",
4432c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber              mCodec->mComponentName.c_str(), err);
4433c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber
4434251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
4435c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
44365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<RefBase> obj;
4439386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    if (msg->findObject("native-window", &obj)
44405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            && strncmp("OMX.google.", mCodec->mComponentName.c_str(), 11)) {
44411173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        sp<NativeWindowWrapper> nativeWindow(
44421173118eace0e9e347cb007f0da817cee87579edGlenn Kasten                static_cast<NativeWindowWrapper *>(obj.get()));
44431173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        CHECK(nativeWindow != NULL);
44441173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        mCodec->mNativeWindow = nativeWindow->getNativeWindow();
44451ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber
44461ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber        native_window_set_scaling_mode(
44471ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                mCodec->mNativeWindow.get(),
44481ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
4449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((status_t)OK, mCodec->initNativeWindow());
4451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
44525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
44535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
4454d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatComponentConfigured);
4455e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("input-format", mCodec->mInputFormat);
4456e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("output-format", mCodec->mOutputFormat);
44575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
44585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4459c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4460c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
44615778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
44625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
44637cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::LoadedState::onCreateInputSurface(
4464ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        const sp<AMessage> & /* msg */) {
44657cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    ALOGV("onCreateInputSurface");
44667cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
44677cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<AMessage> notify = mCodec->mNotify->dup();
4468d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatInputSurfaceCreated);
44697cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
44707cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<IGraphicBufferProducer> bufferProducer;
44717cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    status_t err;
44727cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
44737cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    err = mCodec->mOMX->createInputSurface(mCodec->mNode, kPortIndexInput,
44747cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            &bufferProducer);
4475a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
4476a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    if (err == OK && mCodec->mRepeatFrameDelayUs > 0ll) {
4477a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        err = mCodec->mOMX->setInternalOption(
4478a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                mCodec->mNode,
4479a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                kPortIndexInput,
4480a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY,
4481a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                &mCodec->mRepeatFrameDelayUs,
4482a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                sizeof(mCodec->mRepeatFrameDelayUs));
4483a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
4484a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (err != OK) {
4485a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            ALOGE("[%s] Unable to configure option to repeat previous "
4486a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  "frames (err %d)",
4487a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  mCodec->mComponentName.c_str(),
4488a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  err);
4489a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
4490a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
4491a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
44922c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    if (err == OK && mCodec->mMaxPtsGapUs > 0ll) {
449394ee4b708acfa941581160b267afb79192b1d816Chong Zhang        err = mCodec->mOMX->setInternalOption(
449494ee4b708acfa941581160b267afb79192b1d816Chong Zhang                mCodec->mNode,
449594ee4b708acfa941581160b267afb79192b1d816Chong Zhang                kPortIndexInput,
449694ee4b708acfa941581160b267afb79192b1d816Chong Zhang                IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP,
449794ee4b708acfa941581160b267afb79192b1d816Chong Zhang                &mCodec->mMaxPtsGapUs,
449894ee4b708acfa941581160b267afb79192b1d816Chong Zhang                sizeof(mCodec->mMaxPtsGapUs));
449994ee4b708acfa941581160b267afb79192b1d816Chong Zhang
450094ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (err != OK) {
450194ee4b708acfa941581160b267afb79192b1d816Chong Zhang            ALOGE("[%s] Unable to configure max timestamp gap (err %d)",
450272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    mCodec->mComponentName.c_str(),
450372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    err);
45042c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
45052c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
45062c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
45072c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    if (err == OK && mCodec->mTimePerCaptureUs > 0ll
45082c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            && mCodec->mTimePerFrameUs > 0ll) {
45092c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        int64_t timeLapse[2];
45102c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[0] = mCodec->mTimePerFrameUs;
45112c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[1] = mCodec->mTimePerCaptureUs;
45122c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        err = mCodec->mOMX->setInternalOption(
45132c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                mCodec->mNode,
45142c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                kPortIndexInput,
45152c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                IOMX::INTERNAL_OPTION_TIME_LAPSE,
45162c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                &timeLapse[0],
45172c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                sizeof(timeLapse));
45182c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
45192c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (err != OK) {
45202c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            ALOGE("[%s] Unable to configure time lapse (err %d)",
45212c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    mCodec->mComponentName.c_str(),
45222c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    err);
45232c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
45242c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
452572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
452672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (err == OK && mCodec->mCreateInputBuffersSuspended) {
452772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        bool suspend = true;
452872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        err = mCodec->mOMX->setInternalOption(
452972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                mCodec->mNode,
453072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                kPortIndexInput,
453172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                IOMX::INTERNAL_OPTION_SUSPEND,
453272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                &suspend,
453372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                sizeof(suspend));
453472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
453572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
453672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("[%s] Unable to configure option to suspend (err %d)",
453794ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  mCodec->mComponentName.c_str(),
453894ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  err);
453994ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
454094ee4b708acfa941581160b267afb79192b1d816Chong Zhang    }
454194ee4b708acfa941581160b267afb79192b1d816Chong Zhang
45427cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err == OK) {
45437cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setObject("input-surface",
45447cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                new BufferProducerWrapper(bufferProducer));
45457cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else {
45467cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // Can't use mCodec->signalError() here -- MediaCodec won't forward
45477cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // the error through because it's in the "configured" state.  We
45487cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // send a kWhatInputSurfaceCreated with an error value instead.
45497cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGE("[%s] onCreateInputSurface returning error %d",
45507cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                mCodec->mComponentName.c_str(), err);
45517cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setInt32("err", err);
45527cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
45537cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->post();
45547cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
45557cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4556c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onStart() {
45575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onStart");
45585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
45595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ(mCodec->mOMX->sendCommand(
45605778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
4561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
4562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->changeState(mCodec->mLoadedToIdleState);
4564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4568f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
4569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4572f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::LoadedToIdleState::stateEntered() {
45733856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
4574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4575cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    status_t err;
4576cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    if ((err = allocateBuffers()) != OK) {
457729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to allocate buffers after transitioning to IDLE state "
4578cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             "(error 0x%08x)",
4579cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             err);
4580cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
4581251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
458291bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber
458391bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber        mCodec->changeState(mCodec->mLoadedState);
4584cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    }
4585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4587f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::LoadedToIdleState::allocateBuffers() {
4588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
4589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
4591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
4592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mCodec->allocateBuffersOnPort(kPortIndexOutput);
4595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4597f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
4598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
459972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
4600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
46066507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
46076507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
46086507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
46096507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
46106507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
46116507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
46126463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatResume:
46136463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
46146463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We'll be active soon enough.
46156463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
46166463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
46176463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
46186463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatFlush:
46196463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
46206463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We haven't even started yet, so we're flushed alright...
46216463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            sp<AMessage> notify = mCodec->mNotify->dup();
4622d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
46236463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->post();
46246463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
46256463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
46266463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
4627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
4629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4632f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onOMXEvent(
4633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
4639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
4641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting),
4642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
4643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mIdleToExecutingState);
4645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4656f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
4657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4660f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToExecutingState::stateEntered() {
46613856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
4662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4664f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
4665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
466672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
4667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4673d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatResume:
4674d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
4675d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We'll be active soon enough.
4676d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
4677d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
4678d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
4679d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatFlush:
4680d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
4681d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We haven't even started yet, so we're flushed alright...
4682d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4683d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
4684d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->post();
4685d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
4686d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
4687d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
4688d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
46896507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
46906507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
46916507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
46926507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
46936507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
46946507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
4695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
4697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4700f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onOMXEvent(
4701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateExecuting);
4707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mExecutingState->resume();
4709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingState);
4710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4721f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingState::ExecutingState(ACodec *codec)
4722349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    : BaseState(codec),
4723349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber      mActive(false) {
4724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4726f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
4727ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
4728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
4729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4731054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputMetaBuffers() {
4732054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // submit as many buffers as there are input buffers with the codec
4733054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // in case we are in port reconfiguring
4734054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
4735054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
4736054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4737054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) {
4738054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            if (mCodec->submitOutputMetaDataBuffer() != OK)
4739054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                break;
4740054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
4741054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
47424dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
47434dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
47444dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
4745054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
4746054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4747054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitRegularOutputBuffers() {
4748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
4749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
4750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mCodec->mNativeWindow != NULL) {
4752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(info->mStatus == BufferInfo::OWNED_BY_US
4753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
4754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                continue;
4757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
4759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
4760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
47623856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] calling fillBuffer %p",
4763349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str(), info->mBufferID);
4764349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
4766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
4767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4772054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputBuffers() {
4773c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar    submitRegularOutputBuffers();
4774054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mCodec->mStoreMetaDataInOutputBuffers) {
4775054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        submitOutputMetaBuffers();
4776054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
4777054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
4778054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4779f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::resume() {
4780349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    if (mActive) {
47813856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] We're already active, no need to resume.",
4782349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str());
4783349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4784349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        return;
4785349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    }
4786349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    submitOutputBuffers();
4788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
47893cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    // Post all available input buffers
4790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_GT(mCodec->mBuffers[kPortIndexInput].size(), 0u);
47913cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); i++) {
47923cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
47933cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_US) {
47943cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar            postFillThisBuffer(info);
47953cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        }
47963cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    }
4797349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4798349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    mActive = true;
4799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4801f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::stateEntered() {
48023856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
4803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->processDeferredMessages();
4805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4807f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
4808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4813c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
4814c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
4815c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
4816c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4817c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mShutdownInProgress = true;
481854b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
4819c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mKeepComponentAllocated = keepComponentAllocated;
4820c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4821349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
4822349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
4824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
4825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
4826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingToIdleState);
4828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
48357a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong            ALOGV("[%s] ExecutingState flushing now "
4836d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                 "(codec owns %d/%d input, %d/%d output).",
4837d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mComponentName.c_str(),
4838d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
4839d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexInput].size(),
4840d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
4841d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexOutput].size());
4842d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4843349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
4844349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
4846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandFlush, OMX_ALL),
4847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
4848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mFlushingState);
4850f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatResume:
4855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            resume();
4857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4862496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
4863496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
4864496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            status_t err = mCodec->requestIDRFrame();
4865496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            if (err != OK) {
4866496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                ALOGW("Requesting an IDR frame failed.");
4867496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            }
4868496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4869496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            handled = true;
4870496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
4871496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
4872496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4873a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
4874a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
4875a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
4876a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
4877a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4878a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = mCodec->setParameters(params);
4879a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4880a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> reply;
4881a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            if (msg->findMessage("reply", &reply)) {
4882a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->setInt32("err", err);
4883a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->post();
4884a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            }
4885a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4886a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            handled = true;
4887a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
4888a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
4889a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
48907cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
48917cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
48926507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
48937cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
48947cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
48957cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
48967cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
48974dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
48984dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        case kWhatSubmitOutputMetaDataBufferIfEOS:
48994dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        {
49004dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            if (mCodec->mPortEOS[kPortIndexInput] &&
49014dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    !mCodec->mPortEOS[kPortIndexOutput]) {
49024dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                status_t err = mCodec->submitOutputMetaDataBuffer();
49034dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                if (err == OK) {
49044dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
49054dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                }
49064dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            }
49074dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            return true;
49084dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        }
49094dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
4910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4918a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t ACodec::setParameters(const sp<AMessage> &params) {
4919a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    int32_t videoBitrate;
4920530fdbdc1b5491f3fbf172752834d1515701e142Lajos Molnar    if (params->findInt32("video-bitrate", &videoBitrate)) {
4921a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        OMX_VIDEO_CONFIG_BITRATETYPE configParams;
4922a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        InitOMXParams(&configParams);
4923a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nPortIndex = kPortIndexOutput;
4924a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nEncodeBitrate = videoBitrate;
4925a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4926a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        status_t err = mOMX->setConfig(
4927a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                mNode,
4928a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                OMX_IndexConfigVideoBitrate,
4929a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                &configParams,
4930a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                sizeof(configParams));
4931a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4932a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        if (err != OK) {
4933a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
4934a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                   videoBitrate, err);
4935a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4936a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            return err;
4937a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
4938a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    }
4939a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
494072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    int64_t skipFramesBeforeUs;
494172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (params->findInt64("skip-frames-before", &skipFramesBeforeUs)) {
494272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        status_t err =
494372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mOMX->setInternalOption(
494472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     mNode,
494572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     kPortIndexInput,
494672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     IOMX::INTERNAL_OPTION_START_TIME,
494772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     &skipFramesBeforeUs,
494872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     sizeof(skipFramesBeforeUs));
494972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
495072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
495172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("Failed to set parameter 'skip-frames-before' (err %d)", err);
495272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            return err;
495372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
495472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
495572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
4956e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    int32_t dropInputFrames;
4957e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    if (params->findInt32("drop-input-frames", &dropInputFrames)) {
4958e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        bool suspend = dropInputFrames != 0;
4959e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
4960b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err =
4961b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            mOMX->setInternalOption(
4962e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     mNode,
4963e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     kPortIndexInput,
4964e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     IOMX::INTERNAL_OPTION_SUSPEND,
4965e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     &suspend,
4966b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber                     sizeof(suspend));
4967b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
4968b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
4969b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err);
4970b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
4971b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
4972b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    }
4973b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
4974b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    int32_t dummy;
4975b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    if (params->findInt32("request-sync", &dummy)) {
4976b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err = requestIDRFrame();
4977b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
4978b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
4979b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Requesting a sync frame failed w/ err %d", err);
4980b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
4981b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
4982e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    }
4983e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
4984a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return OK;
4985a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
4986a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
49876507d14c6d10f93d390de62b9eed267f9b544985Andy McFaddenvoid ACodec::onSignalEndOfInputStream() {
49886507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    sp<AMessage> notify = mNotify->dup();
4989d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatSignaledInputEOS);
49906507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
49916507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    status_t err = mOMX->signalEndOfInputStream(mNode);
49926507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    if (err != OK) {
49936507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        notify->setInt32("err", err);
49946507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    }
49956507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->post();
49966507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden}
49976507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
4998f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onOMXEvent(
4999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventPortSettingsChanged:
5002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
5004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
500531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
5006054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mCodec->mMetaDataBuffersToSubmit = 0;
5007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
5008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
5009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_CommandPortDisable, kPortIndexOutput),
5010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
5011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5012349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                mCodec->freeOutputBuffersNotOwnedByComponent();
5013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
501531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            } else if (data2 == OMX_IndexConfigCommonOutputCrop) {
501631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
5017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
50183856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08lx",
5019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->mComponentName.c_str(), data2);
5020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventBufferFlag:
5026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5037f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
5038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ACodec *codec)
5039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5042f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
5043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
5044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput) {
5045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return FREE_BUFFERS;
5046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
5049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
5051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5053f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onMessageReceived(
5054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
5055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5060349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case kWhatResume:
5061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5062349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            if (msg->what() == kWhatResume) {
50633856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
5064349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            }
5065349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
5067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5079f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::OutputPortSettingsChangedState::stateEntered() {
50803856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now handling output port settings change",
5081f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mCodec->mComponentName.c_str());
5082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5084f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onOMXEvent(
5085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5086f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5089f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
5090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
5091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
50923856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now disabled.",
5093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
5094f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5095f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mCodec->mBuffers[kPortIndexOutput].isEmpty());
5096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mDealer[kPortIndexOutput].clear();
5097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
5099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput),
5100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
5101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5102cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                status_t err;
5103cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                if ((err = mCodec->allocateBuffersOnPort(
5104cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                                kPortIndexOutput)) != OK) {
510529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("Failed to allocate output port buffers after "
5106cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         "port reconfiguration (error 0x%08x)",
5107cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         err);
5108cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
5109251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5110d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
5111755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // This is technically not correct, but appears to be
5112755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the only way to free the component instance.
5113755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // Controlled transitioning from excecuting->idle
5114755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // and idle->loaded seem impossible probably because
5115755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the output port never finishes re-enabling.
5116755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mShutdownInProgress = true;
5117755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mKeepComponentAllocated = false;
5118755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->changeState(mCodec->mLoadedState);
5119cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                }
5120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
5122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
5123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
5124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
512531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
512631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
51273856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now reenabled.",
5128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
5129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5130349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                if (mCodec->mExecutingState->active()) {
5131349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    mCodec->mExecutingState->submitOutputBuffers();
5132349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                }
5133349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mExecutingState);
5135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
5137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
5140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
5144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5149f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
51505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : BaseState(codec),
51515778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mComponentNowIdle(false) {
5152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5154f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
5155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
5161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
5162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
5163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
5169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5182f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::stateEntered() {
51833856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
518431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
51855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mComponentNowIdle = false;
518631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mCodec->mSentFormat = false;
5187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5189f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onOMXEvent(
5190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
5195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
5196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
51975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mComponentNowIdle = true;
51985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            changeStateIfWeOwnAllBuffers();
5200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5204349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
5205349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventBufferFlag:
5206349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
5207349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We're shutting down and don't care about this anymore.
5208349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
5209349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
5210349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
52150af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
5216f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
52175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
5218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->sendCommand(
5219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded),
5220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
5221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexInput), (status_t)OK);
5223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexOutput), (status_t)OK);
5224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
52250167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown)
52260167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && mCodec->mNativeWindow != NULL) {
5227bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // We push enough 1x1 blank buffers to ensure that one of
5228bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // them has made it to the display.  This allows the OMX
5229bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // component teardown to zero out any protected buffers
5230bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // without the risk of scanning out one of those buffers.
5231bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            mCodec->pushBlankBuffersToNativeWindow();
5232bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
5233bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
5234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mIdleToLoadedState);
5235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5238f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onInputBufferFilled(
5239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
5240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
5241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
5243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5245f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onOutputBufferDrained(
5246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
5247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
5248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
5250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5254f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
5255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5258f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
5259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
5265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
5273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
5274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
5275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5286f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToLoadedState::stateEntered() {
52873856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
5288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5290f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onOMXEvent(
5291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
5296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateLoaded);
5297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5298c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->changeState(mCodec->mLoadedState);
5299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5310f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::FlushingState::FlushingState(ACodec *codec)
5311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5314f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::stateEntered() {
53153856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
5316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
5318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5320f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
5321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
5327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing this right now.
5333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5345f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onOMXEvent(
5346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
53477a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] FlushingState onOMXEvent(%d,%ld)",
5348d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            mCodec->mComponentName.c_str(), event, data1);
5349d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
5350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandFlush);
5354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
5356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(!mFlushComplete[data2]);
5357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mFlushComplete[data2] = true;
5358e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber
5359e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                if (mFlushComplete[kPortIndexInput]
5360e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                        && mFlushComplete[kPortIndexOutput]) {
5361e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                    changeStateIfWeOwnAllBuffers();
5362e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                }
5363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
5364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, OMX_ALL);
5365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexInput]);
5366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexOutput]);
5367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                changeStateIfWeOwnAllBuffers();
5369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5374349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
5375349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
5376349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec->id());
5377349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("type", omx_message::EVENT);
5378609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            msg->setInt32("node", mCodec->mNode);
5379349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("event", event);
5380349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data1", data1);
5381349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data2", data2);
5382349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
53833856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
5384349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                 mCodec->mComponentName.c_str());
5385349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5386349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mCodec->deferMessage(msg);
5387349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5388349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
5389349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
5390349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
5396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5398f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
5399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
5400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
5402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5404f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
5405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
5406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
5408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5410f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
5411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mFlushComplete[kPortIndexInput]
5412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mFlushComplete[kPortIndexOutput]
5413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mCodec->allYourBuffersAreBelongToUs()) {
54147e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // We now own all buffers except possibly those still queued with
54157e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // the native window for rendering. Let's get those back as well.
54167e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
54177e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
5418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
5419d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatFlushCompleted);
5420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->post();
5421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->mPortEOS[kPortIndexInput] =
5423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mPortEOS[kPortIndexOutput] = false;
5424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5425dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber        mCodec->mInputEOSResult = OK;
5426dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
5427f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        if (mCodec->mSkipCutBuffer != NULL) {
5428f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen            mCodec->mSkipCutBuffer->clear();
5429f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        }
5430f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen
5431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mExecutingState);
5432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
5436