ACodec.cpp revision 30358faf33fb9b638257b017fadb4c5f7352d903
127c174483a8ae9688d5d4897c19074f62c7f1701James Dong/*
227c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Copyright (C) 2010 The Android Open Source Project
327c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
427c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Licensed under the Apache License, Version 2.0 (the "License");
527c174483a8ae9688d5d4897c19074f62c7f1701James Dong * you may not use this file except in compliance with the License.
627c174483a8ae9688d5d4897c19074f62c7f1701James Dong * You may obtain a copy of the License at
727c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
827c174483a8ae9688d5d4897c19074f62c7f1701James Dong *      http://www.apache.org/licenses/LICENSE-2.0
927c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
1027c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Unless required by applicable law or agreed to in writing, software
1127c174483a8ae9688d5d4897c19074f62c7f1701James Dong * distributed under the License is distributed on an "AS IS" BASIS,
1227c174483a8ae9688d5d4897c19074f62c7f1701James Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1327c174483a8ae9688d5d4897c19074f62c7f1701James Dong * See the License for the specific language governing permissions and
1427c174483a8ae9688d5d4897c19074f62c7f1701James Dong * limitations under the License.
1527c174483a8ae9688d5d4897c19074f62c7f1701James Dong */
1627c174483a8ae9688d5d4897c19074f62c7f1701James Dong
17f933441648ef6a71dee783d733aac17b9508b452Andreas Huber//#define LOG_NDEBUG 0
18f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#define LOG_TAG "ACodec"
19f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
20f87e30fe71752dc431d8e8d5682c38271c03265aAndy Hung#ifdef __LP64__
21f87e30fe71752dc431d8e8d5682c38271c03265aAndy Hung#define OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
22f87e30fe71752dc431d8e8d5682c38271c03265aAndy Hung#endif
23f87e30fe71752dc431d8e8d5682c38271c03265aAndy Hung
24609b815a3131d22da38b2f452faa9f89daad4039Andy Hung#include <inttypes.h>
256fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar#include <utils/Trace.h>
266fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar
27f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/ACodec.h>
28f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
29f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <binder/MemoryDealer.h>
30f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/hexdump.h>
32f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ABuffer.h>
33f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ADebug.h>
34f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/AMessage.h>
35a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar#include <media/stagefright/foundation/AUtils.h>
36f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
377cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden#include <media/stagefright/BufferProducerWrapper.h>
38afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber#include <media/stagefright/MediaCodecList.h>
39f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaDefs.h>
401173118eace0e9e347cb007f0da817cee87579edGlenn Kasten#include <media/stagefright/NativeWindowWrapper.h>
41f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/OMXClient.h>
421065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber#include <media/stagefright/OMXCodec.h>
43f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
443a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber#include <media/hardware/HardwareAPI.h>
453a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
4697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu#include <OMX_AudioExt.h>
474154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev#include <OMX_VideoExt.h>
48f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <OMX_Component.h>
4997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu#include <OMX_IndexExt.h>
50f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
51496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#include "include/avc_utils.h"
52496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
53f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android {
54f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
55251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// OMX errors are directly mapped into status_t range if
56251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// there is no corresponding MediaError status code.
57251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Use the statusFromOMXError(int32_t omxError) function.
58251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung//
59251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Currently this is a direct map.
60251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// See frameworks/native/include/media/openmax/OMX_Core.h
61251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung//
62251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Vendor OMX errors     from 0x90000000 - 0x9000FFFF
63251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Extension OMX errors  from 0x8F000000 - 0x90000000
64251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Standard OMX errors   from 0x80001000 - 0x80001024 (0x80001024 current)
65251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung//
66251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
67251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// returns true if err is a recognized OMX error code.
68251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// as OMX error is OMX_S32, this is an int32_t type
69251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hungstatic inline bool isOMXError(int32_t err) {
70251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    return (ERROR_CODEC_MIN <= err && err <= ERROR_CODEC_MAX);
71251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung}
72251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
73251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// converts an OMX error to a status_t
74251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hungstatic inline status_t statusFromOMXError(int32_t omxError) {
75251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    switch (omxError) {
76251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case OMX_ErrorInvalidComponentName:
77251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case OMX_ErrorComponentNotFound:
78251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return NAME_NOT_FOUND; // can trigger illegal argument error for provided names.
79251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    default:
80251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return isOMXError(omxError) ? omxError : 0; // no translation required
81251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
82251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung}
83251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
84251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// checks and converts status_t to a non-side-effect status_t
85251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hungstatic inline status_t makeNoSideEffectStatus(status_t err) {
86251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    switch (err) {
87251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // the following errors have side effects and may come
88251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // from other code modules. Remap for safety reasons.
89251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case INVALID_OPERATION:
90251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case DEAD_OBJECT:
91251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return UNKNOWN_ERROR;
92251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    default:
93251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return err;
94251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
95251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung}
96251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
97f933441648ef6a71dee783d733aac17b9508b452Andreas Hubertemplate<class T>
98f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic void InitOMXParams(T *params) {
99f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nSize = sizeof(T);
100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nVersionMajor = 1;
101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nVersionMinor = 0;
102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nRevision = 0;
103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nStep = 0;
104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
106f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct CodecObserver : public BnOMXObserver {
107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CodecObserver() {}
108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void setNotificationMessage(const sp<AMessage> &msg) {
110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mNotify = msg;
111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // from IOMXObserver
114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onMessage(const omx_message &omx_msg) {
115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> msg = mNotify->dup();
116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->setInt32("type", omx_msg.type);
118609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        msg->setInt32("node", omx_msg.node);
119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        switch (omx_msg.type) {
121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::EVENT:
122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("event", omx_msg.u.event_data.event);
124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("data1", omx_msg.u.event_data.data1);
125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("data2", omx_msg.u.event_data.data2);
126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::EMPTY_BUFFER_DONE:
130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
131609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                msg->setInt32("buffer", omx_msg.u.buffer_data.buffer);
132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::FILL_BUFFER_DONE:
136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
137609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                msg->setInt32(
138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "buffer", omx_msg.u.extended_buffer_data.buffer);
139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "range_offset",
141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.range_offset);
142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "range_length",
144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.range_length);
145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "flags",
147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.flags);
148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt64(
149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "timestamp",
150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.timestamp);
151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            default:
155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                TRESPASS();
156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->post();
160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
162f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual ~CodecObserver() {}
164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
165f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> mNotify;
167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(CodecObserver);
169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
173f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::BaseState : public AState {
174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState(ACodec *codec, const sp<AState> &parentState = NULL);
175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
176f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    enum PortMode {
178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        KEEP_BUFFERS,
179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        RESUBMIT_BUFFERS,
180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        FREE_BUFFERS,
181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ACodec *mCodec;
184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void postFillThisBuffer(BufferInfo *info);
195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
196f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXMessage(const sp<AMessage> &msg);
198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXEmptyBufferDone(IOMX::buffer_id bufferID);
200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXFillBufferDone(
202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID,
203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            size_t rangeOffset, size_t rangeLength,
204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            OMX_U32 flags,
205784e24e386b088c05d653ab482f2e95cb53e3d01Andy Hung            int64_t timeUs);
206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void getMoreInputDataIfPossible();
208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(BaseState);
210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
214ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberstruct ACodec::DeathNotifier : public IBinder::DeathRecipient {
215ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    DeathNotifier(const sp<AMessage> &notify)
216ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        : mNotify(notify) {
217ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
218ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
219ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual void binderDied(const wp<IBinder> &) {
220ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mNotify->post();
221ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
222ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
223ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprotected:
224ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual ~DeathNotifier() {}
225ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
226ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprivate:
227ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> mNotify;
228ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
229ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(DeathNotifier);
230ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber};
231ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
232f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::UninitializedState : public ACodec::BaseState {
233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    UninitializedState(ACodec *codec);
234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
235f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
237c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
239f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void onSetup(const sp<AMessage> &msg);
241c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onAllocateComponent(const sp<AMessage> &msg);
242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
243ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<DeathNotifier> mDeathNotifier;
244ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(UninitializedState);
246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
250c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberstruct ACodec::LoadedState : public ACodec::BaseState {
251c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    LoadedState(ACodec *codec);
252c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
253c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprotected:
254c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
255c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
256c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
257c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprivate:
258c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    friend struct ACodec::UninitializedState;
259c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
260c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onConfigureComponent(const sp<AMessage> &msg);
2617cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    void onCreateInputSurface(const sp<AMessage> &msg);
262c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onStart();
263c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onShutdown(bool keepComponentAllocated);
264c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
265c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedState);
266c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber};
267c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
268c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
269c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
270f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::LoadedToIdleState : public ACodec::BaseState {
271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    LoadedToIdleState(ACodec *codec);
272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
273f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
278f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t allocateBuffers();
280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedToIdleState);
282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
286f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToExecutingState : public ACodec::BaseState {
287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToExecutingState(ACodec *codec);
288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
289f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
294f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToExecutingState);
296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
300f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingState : public ACodec::BaseState {
301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingState(ACodec *codec);
302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
303054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitRegularOutputBuffers();
304054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitOutputMetaBuffers();
305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void submitOutputBuffers();
306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Submit output buffers to the decoder, submit input buffers to client
308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // to fill with data.
309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void resume();
310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
311349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    // Returns true iff input and output buffers are in play.
312349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool active() const { return mActive; }
313349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
314f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
321f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
322349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool mActive;
323349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingState);
325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
329f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::OutputPortSettingsChangedState : public ACodec::BaseState {
330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OutputPortSettingsChangedState(ACodec *codec);
331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
332f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
339f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(OutputPortSettingsChangedState);
341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
345f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingToIdleState : public ACodec::BaseState {
346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingToIdleState(ACodec *codec);
347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
348f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
357f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool mComponentNowIdle;
3615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingToIdleState);
363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
367f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToLoadedState : public ACodec::BaseState {
368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToLoadedState(ACodec *codec);
369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
370f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
376f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToLoadedState);
378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
382f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::FlushingState : public ACodec::BaseState {
383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    FlushingState(ACodec *codec);
384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
385f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
394f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool mFlushComplete[2];
396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(FlushingState);
400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
404f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ACodec()
405afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    : mQuirks(0),
406609b815a3131d22da38b2f452faa9f89daad4039Andy Hung      mNode(0),
4075778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mSentFormat(false),
408c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber      mIsEncoder(false),
409308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang      mUseMetadataOnEncoderOutput(false),
4109806555d3930be43e11106281dee354820ac1c88Andreas Huber      mShutdownInProgress(false),
41154b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar      mExplicitShutdown(false),
4129806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderDelay(0),
4139806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderPadding(0),
414e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang      mRotationDegrees(0),
4159806555d3930be43e11106281dee354820ac1c88Andreas Huber      mChannelMaskPresent(false),
416054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mChannelMask(0),
417054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mDequeueCounter(0),
418054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mStoreMetaDataInOutputBuffers(false),
419a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber      mMetaDataBuffersToSubmit(0),
42094ee4b708acfa941581160b267afb79192b1d816Chong Zhang      mRepeatFrameDelayUs(-1ll),
4212c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang      mMaxPtsGapUs(-1ll),
4222c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang      mTimePerFrameUs(-1ll),
423609b815a3131d22da38b2f452faa9f89daad4039Andy Hung      mTimePerCaptureUs(-1ll),
424ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad      mCreateInputBuffersSuspended(false),
425ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad      mTunneled(false) {
426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mUninitializedState = new UninitializedState(this);
427c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mLoadedState = new LoadedState(this);
428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mLoadedToIdleState = new LoadedToIdleState(this);
429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToExecutingState = new IdleToExecutingState(this);
430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingState = new ExecutingState(this);
431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOutputPortSettingsChangedState =
433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        new OutputPortSettingsChangedState(this);
434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingToIdleState = new ExecutingToIdleState(this);
436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToLoadedState = new IdleToLoadedState(this);
437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushingState = new FlushingState(this);
438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
440dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber    mInputEOSResult = OK;
441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeState(mUninitializedState);
443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
445f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::~ACodec() {
446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
448f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::setNotificationMessage(const sp<AMessage> &msg) {
449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mNotify = msg;
450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
452f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::initiateSetup(const sp<AMessage> &msg) {
453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setWhat(kWhatSetup);
454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setTarget(id());
455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
458a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Hubervoid ACodec::signalSetParameters(const sp<AMessage> &params) {
459a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    sp<AMessage> msg = new AMessage(kWhatSetParameters, id());
460a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->setMessage("params", params);
461a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->post();
462a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
463a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4645778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateAllocateComponent(const sp<AMessage> &msg) {
4655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatAllocateComponent);
4665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
4675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4685778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4705778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateConfigureComponent(const sp<AMessage> &msg) {
4715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatConfigureComponent);
4725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
4735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4745778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4767cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::initiateCreateInputSurface() {
4777cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    (new AMessage(kWhatCreateInputSurface, id()))->post();
4787cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
4797cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4807cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::signalEndOfInputStream() {
4817cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    (new AMessage(kWhatSignalEndOfInputStream, id()))->post();
4827cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
4837cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4845778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateStart() {
4855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    (new AMessage(kWhatStart, id()))->post();
4865778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
488f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalFlush() {
4897a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] signalFlush", mComponentName.c_str());
490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatFlush, id()))->post();
491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
493f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalResume() {
494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatResume, id()))->post();
495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
497c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::initiateShutdown(bool keepComponentAllocated) {
498c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> msg = new AMessage(kWhatShutdown, id());
499c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->setInt32("keepComponentAllocated", keepComponentAllocated);
500c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->post();
50130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar    if (!keepComponentAllocated) {
50230358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        // ensure shutdown completes in 3 seconds
50330358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        (new AMessage(kWhatReleaseCodecInstance, id()))->post(3000000);
50430358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar    }
505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
507496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubervoid ACodec::signalRequestIDRFrame() {
508496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    (new AMessage(kWhatRequestIDRFrame, id()))->post();
509496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
510496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5114dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
5124dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// Some codecs may return input buffers before having them processed.
5134dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// This causes a halt if we already signaled an EOS on the input
5144dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// port.  For now keep submitting an output buffer if there was an
5154dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// EOS on the input port, but not yet on the output port.
5164dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnarvoid ACodec::signalSubmitOutputMetaDataBufferIfEOS_workaround() {
5174dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    if (mPortEOS[kPortIndexInput] && !mPortEOS[kPortIndexOutput] &&
5184dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            mMetaDataBuffersToSubmit > 0) {
5194dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        (new AMessage(kWhatSubmitOutputMetaDataBufferIfEOS, id()))->post();
5204dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    }
5214dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar}
5224dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
523f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mDealer[portIndex] == NULL);
527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mBuffers[portIndex].isEmpty());
528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
531054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (mStoreMetaDataInOutputBuffers) {
532054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputMetaDataBuffers();
533054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
534054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputBuffersFromNativeWindow();
535054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
5365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
5375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
5385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
5395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = portIndex;
540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
5425778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err == OK) {
545609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGV("[%s] Allocating %u buffers of size %u on %s port",
5465778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mComponentName.c_str(),
5475778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    def.nBufferCountActual, def.nBufferSize,
5485778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    portIndex == kPortIndexInput ? "input" : "output");
549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            size_t totalSize = def.nBufferCountActual * def.nBufferSize;
5515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
5545778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
5555778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(mem.get() != NULL);
556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
557ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                BufferInfo info;
558ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                info.mStatus = BufferInfo::OWNED_BY_US;
559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
560afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                uint32_t requiresAllocateBufferBit =
561afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                    (portIndex == kPortIndexInput)
562afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        ? OMXCodec::kRequiresAllocateBufferOnInputPorts
563afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        : OMXCodec::kRequiresAllocateBufferOnOutputPorts;
5641065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
565308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                if ((portIndex == kPortIndexInput && (mFlags & kFlagIsSecure))
566308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        || mUseMetadataOnEncoderOutput) {
567ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    mem.clear();
568ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
569ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    void *ptr;
570ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->allocateBuffer(
571ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, def.nBufferSize, &info.mBufferID,
572ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            &ptr);
573ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
574308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    int32_t bufSize = mUseMetadataOnEncoderOutput ?
575308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                            (4 + sizeof(buffer_handle_t)) : def.nBufferSize;
576308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
577308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    info.mData = new ABuffer(ptr, bufSize);
578ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                } else if (mQuirks & requiresAllocateBufferBit) {
5795778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    err = mOMX->allocateBufferWithBackup(
580ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, mem, &info.mBufferID);
5815778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
582ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->useBuffer(mNode, portIndex, mem, &info.mBufferID);
583ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                }
584ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
585ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                if (mem != NULL) {
586ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    info.mData = new ABuffer(mem->pointer(), def.nBufferSize);
5875778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
5881065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
5895778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mBuffers[portIndex].push(info);
5901065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            }
5911065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
5925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
5955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
5965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> notify = mNotify->dup();
599d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatBuffersAllocated);
6005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("portIndex", portIndex);
602eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
603eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    sp<PortDescription> desc = new PortDescription;
604eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
6055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
606eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        const BufferInfo &info = mBuffers[portIndex][i];
6075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
608eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        desc->addBuffer(info.mBufferID, info.mData);
609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
611eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    notify->setObject("portDesc", desc);
6125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->post();
6135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
617054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::configureOutputBuffersFromNativeWindow(
618054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 *bufferCount, OMX_U32 *bufferSize,
619054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 *minUndequeuedBuffers) {
620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = kPortIndexOutput;
623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffers_geometry(
632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameWidth,
634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameHeight,
635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.eColorFormat);
636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
63829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffers_geometry failed: %s (%d)",
639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                strerror(-err), -err);
640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
643e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang    if (mRotationDegrees != 0) {
644e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        uint32_t transform = 0;
645e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        switch (mRotationDegrees) {
646e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            case 0: transform = 0; break;
647e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            case 90: transform = HAL_TRANSFORM_ROT_90; break;
648e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            case 180: transform = HAL_TRANSFORM_ROT_180; break;
649e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            case 270: transform = HAL_TRANSFORM_ROT_270; break;
650e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            default: transform = 0; break;
651e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        }
652e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang
653e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        if (transform > 0) {
654e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            err = native_window_set_buffers_transform(
655e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang                    mNativeWindow.get(), transform);
656e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            if (err != 0) {
657e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang                ALOGE("native_window_set_buffers_transform failed: %s (%d)",
658e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang                        strerror(-err), -err);
659e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang                return err;
660e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            }
661e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        }
662e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang    }
663e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang
664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Set up the native window.
6653c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    OMX_U32 usage = 0;
6663c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
6673c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    if (err != 0) {
6685ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("querying usage flags from OMX IL component failed: %d", err);
6693c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        // XXX: Currently this error is logged, but not fatal.
6703c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        usage = 0;
6713c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    }
6723c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis
673bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (mFlags & kFlagIsSecure) {
674bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        usage |= GRALLOC_USAGE_PROTECTED;
675bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
676bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
677bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // Make sure to check whether either Stagefright or the video decoder
678bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // requested protected buffers.
679bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (usage & GRALLOC_USAGE_PROTECTED) {
680bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Verify that the ANativeWindow sends images directly to
681bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // SurfaceFlinger.
682bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        int queuesToNativeWindow = 0;
683bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->query(
684bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                mNativeWindow.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
685bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                &queuesToNativeWindow);
686bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != 0) {
687bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error authenticating native window: %d", err);
688bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
689bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
690bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (queuesToNativeWindow != 1) {
691bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("native window could not be authenticated");
692bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return PERMISSION_DENIED;
693bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
694bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
695bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_usage(
697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
6983c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis            usage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP);
699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
70129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err);
702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
705ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // Exits here for tunneled video playback codecs -- i.e. skips native window
706ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // buffer allocation step as this is managed by the tunneled OMX omponent
707ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // itself and explicitly sets def.nBufferCountActual to 0.
708ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    if (mTunneled) {
709ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        ALOGV("Tunneled Playback: skipping native window buffer allocation.");
710ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        def.nBufferCountActual = 0;
711ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        err = mOMX->setParameter(
712ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
713ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
714ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *minUndequeuedBuffers = 0;
715ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *bufferCount = 0;
716ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *bufferSize = 0;
717ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        return err;
718ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    }
719ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
720054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *minUndequeuedBuffers = 0;
721258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    err = mNativeWindow->query(
722258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
723054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (int *)minUndequeuedBuffers);
724258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
725258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    if (err != 0) {
72629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
727258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                strerror(-err), -err);
728258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        return err;
729258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
730258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
731e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // FIXME: assume that surface is controlled by app (native window
732e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // returns the number for the case when surface is not controlled by app)
7331faa41704e0b976e546321effcb09a85767d51baLajos Molnar    // FIXME2: This means that minUndeqeueudBufs can be 1 larger than reported
7341faa41704e0b976e546321effcb09a85767d51baLajos Molnar    // For now, try to allocate 1 more buffer, but don't fail if unsuccessful
735e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar
736e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // Use conservative allocation while also trying to reduce starvation
737e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //
738e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // 1. allocate at least nBufferCountMin + minUndequeuedBuffers - that is the
739e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //    minimum needed for the consumer to be able to work
740e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // 2. try to allocate two (2) additional buffers to reduce starvation from
741e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //    the consumer
7421faa41704e0b976e546321effcb09a85767d51baLajos Molnar    //    plus an extra buffer to account for incorrect minUndequeuedBufs
7431faa41704e0b976e546321effcb09a85767d51baLajos Molnar    for (OMX_U32 extraBuffers = 2 + 1; /* condition inside loop */; extraBuffers--) {
744e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        OMX_U32 newBufferCount =
745e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            def.nBufferCountMin + *minUndequeuedBuffers + extraBuffers;
746258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        def.nBufferCountActual = newBufferCount;
747258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        err = mOMX->setParameter(
748258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
749258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
750e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        if (err == OK) {
751e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            *minUndequeuedBuffers += extraBuffers;
752e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            break;
753e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        }
754e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar
755609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGW("[%s] setting nBufferCountActual to %u failed: %d",
756e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar                mComponentName.c_str(), newBufferCount, err);
757e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        /* exit condition */
758e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        if (extraBuffers == 0) {
759258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            return err;
760258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        }
761258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
762258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffer_count(
764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(), def.nBufferCountActual);
765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
76729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                -err);
769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
772054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferCount = def.nBufferCountActual;
773054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferSize =  def.nBufferSize;
774054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
775054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
776054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
777054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputBuffersFromNativeWindow() {
778054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
779054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
780054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
781054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
782054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
783e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    mNumUndequeuedBuffers = minUndequeuedBuffers;
784054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
785609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Allocating %u buffers from a native window of size %u on "
786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         "output port",
787054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount, bufferSize);
788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Dequeue buffers and send them to OMX
790054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
7918ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev        ANativeWindowBuffer *buf;
7921e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
79429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
79974006804065941841883c4b46ee785070164023fJamie Gennis        BufferInfo info;
80074006804065941841883c4b46ee785070164023fJamie Gennis        info.mStatus = BufferInfo::OWNED_BY_US;
801054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(NULL /* data */, bufferSize /* capacity */);
80274006804065941841883c4b46ee785070164023fJamie Gennis        info.mGraphicBuffer = graphicBuffer;
80374006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].push(info);
80474006804065941841883c4b46ee785070164023fJamie Gennis
805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferId;
806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &bufferId);
808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
809609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGE("registering GraphicBuffer %u with OMX IL component failed: "
81074006804065941841883c4b46ee785070164023fJamie Gennis                 "%d", i, err);
811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
81474006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
81574006804065941841883c4b46ee785070164023fJamie Gennis
816609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGV("[%s] Registered graphic buffer with ID %u (pointer = %p)",
817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mComponentName.c_str(),
818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             bufferId, graphicBuffer.get());
819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelStart;
822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelEnd;
823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // If an error occurred while dequeuing we need to cancel any buffers
826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // that were dequeued.
827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelStart = 0;
82874006804065941841883c4b46ee785070164023fJamie Gennis        cancelEnd = mBuffers[kPortIndexOutput].size();
829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
830054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // Return the required minimum undequeued buffers to the native window.
831054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelStart = bufferCount - minUndequeuedBuffers;
832054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelEnd = bufferCount;
833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
8373fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        status_t error = cancelBufferToNativeWindow(info);
8383fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        if (err == 0) {
8393fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia            err = error;
8403fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        }
841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
846054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputMetaDataBuffers() {
847054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
848054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
849054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
850054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
851054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
852e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    mNumUndequeuedBuffers = minUndequeuedBuffers;
853054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
854609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Allocating %u meta buffers on output port",
855054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount);
856054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
857054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    size_t totalSize = bufferCount * 8;
858054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mDealer[kPortIndexOutput] = new MemoryDealer(totalSize, "ACodec");
859054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
860054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // Dequeue buffers and send them to OMX
861054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
862054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo info;
863054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
864054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mGraphicBuffer = NULL;
865054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mDequeuedAt = mDequeueCounter;
866054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
867054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        sp<IMemory> mem = mDealer[kPortIndexOutput]->allocate(
868054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                sizeof(struct VideoDecoderOutputMetaData));
869054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(mem.get() != NULL);
870054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(mem->pointer(), mem->size());
871054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
872054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // we use useBuffer for metadata regardless of quirks
873054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        err = mOMX->useBuffer(
874054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mNode, kPortIndexOutput, mem, &info.mBufferID);
875054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
876054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        mBuffers[kPortIndexOutput].push(info);
877054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
878609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGV("[%s] allocated meta buffer with ID %u (pointer = %p)",
879054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mComponentName.c_str(), info.mBufferID, mem->pointer());
880054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
881054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
882054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mMetaDataBuffersToSubmit = bufferCount - minUndequeuedBuffers;
883054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
884054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
885054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
886054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::submitOutputMetaDataBuffer() {
887054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mStoreMetaDataInOutputBuffers);
888054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mMetaDataBuffersToSubmit == 0)
889054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return OK;
890054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
891054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *info = dequeueBufferFromNativeWindow();
892054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (info == NULL)
893054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return ERROR_IO;
894054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
895609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] submitting output meta buffer ID %u for graphic buffer %p",
896054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          mComponentName.c_str(), info->mBufferID, info->mGraphicBuffer.get());
897054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
898054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    --mMetaDataBuffersToSubmit;
899054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK_EQ(mOMX->fillBuffer(mNode, info->mBufferID),
900054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             (status_t)OK);
901054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
902054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
903054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return OK;
904054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
905054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
906f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
909609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Calling cancelBuffer on buffer %u",
910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mComponentName.c_str(), info->mBufferID);
911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int err = mNativeWindow->cancelBuffer(
9131e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        mNativeWindow.get(), info->mGraphicBuffer.get(), -1);
914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9153fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia    ALOGW_IF(err != 0, "[%s] can not return buffer %u to native window",
9163fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia            mComponentName.c_str(), info->mBufferID);
917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9203fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia    return err;
921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
923f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
9248ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev    ANativeWindowBuffer *buf;
9251e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    int fenceFd = -1;
926054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mNativeWindow.get() != NULL);
927ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
928ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    if (mTunneled) {
929ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        ALOGW("dequeueBufferFromNativeWindow() should not be called in tunnel"
930ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad              " video playback mode mode!");
931ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        return NULL;
932ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    }
933ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
9341e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    if (native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf) != 0) {
93529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("dequeueBuffer failed.");
936c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber        return NULL;
937c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
939054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *oldest = NULL;
940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
944054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mGraphicBuffer != NULL &&
945054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            info->mGraphicBuffer->handle == buf->handle) {
946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus,
947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (int)BufferInfo::OWNED_BY_NATIVE_WINDOW);
948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
953054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
954054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW &&
955054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (oldest == NULL ||
956054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             // avoid potential issues from counter rolling over
957054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mDequeueCounter - info->mDequeuedAt >
958054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    mDequeueCounter - oldest->mDequeuedAt)) {
959054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            oldest = info;
960054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
961054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
962054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
963054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (oldest) {
964054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(mStoreMetaDataInOutputBuffers);
965054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
966054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // discard buffer in LRU info and replace with new buffer
967054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mGraphicBuffer = new GraphicBuffer(buf, false);
968054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mStatus = BufferInfo::OWNED_BY_US;
969054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
970d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        mOMX->updateGraphicBufferInMeta(
971d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                mNode, kPortIndexOutput, oldest->mGraphicBuffer,
972d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                oldest->mBufferID);
973054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
974d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        VideoDecoderOutputMetaData *metaData =
975d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar            reinterpret_cast<VideoDecoderOutputMetaData *>(
976d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                    oldest->mData->base());
977d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        CHECK_EQ(metaData->eType, kMetadataBufferTypeGrallocSource);
978d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar
979d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
980054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                oldest - &mBuffers[kPortIndexOutput][0],
981054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mDequeueCounter - oldest->mDequeuedAt,
982d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                metaData->pHandle,
983d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                oldest->mGraphicBuffer->handle, oldest->mData->base());
984054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
985054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return oldest;
986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
993f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[portIndex].size(); i-- > 0;) {
995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, freeBuffer(portIndex, i));
996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDealer[portIndex].clear();
999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1003349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huberstatus_t ACodec::freeOutputBuffersNotOwnedByComponent() {
1004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
1005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
1006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
1007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10082ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // At this time some buffers may still be with the component
10092ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // or being drained.
10102ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT &&
10112ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar            info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) {
1012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK, freeBuffer(kPortIndexOutput, i));
1013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1019f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
1020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
1021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(info->mStatus == BufferInfo::OWNED_BY_US
1023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
1024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput && mNativeWindow != NULL
1026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && info->mStatus == BufferInfo::OWNED_BY_US) {
10273fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        cancelBufferToNativeWindow(info);
1028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(mOMX->freeBuffer(
1031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, portIndex, info->mBufferID),
1032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
1033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mBuffers[portIndex].removeAt(i);
1035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1039f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::findBufferByID(
1040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        uint32_t portIndex, IOMX::buffer_id bufferID,
1041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ssize_t *index) {
1042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
1043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
1044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mBufferID == bufferID) {
1046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (index != NULL) {
1047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                *index = i;
1048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
1050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
1054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
1056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10585778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setComponentRole(
1059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        bool isEncoder, const char *mime) {
1060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    struct MimeToRole {
1061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime;
1062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *decoderRole;
1063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *encoderRole;
1064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
1065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const MimeToRole kMimeToRole[] = {
1067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG,
1068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.mp3", "audio_encoder.mp3" },
10692944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
10702944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp1", "audio_encoder.mp1" },
10712944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
10722944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp2", "audio_encoder.mp2" },
1073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_NB,
1074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrnb", "audio_encoder.amrnb" },
1075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_WB,
1076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrwb", "audio_encoder.amrwb" },
1077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AAC,
1078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.aac", "audio_encoder.aac" },
1079729de186450f78c099637e1fce743fe531862c52Andreas Huber        { MEDIA_MIMETYPE_AUDIO_VORBIS,
1080729de186450f78c099637e1fce743fe531862c52Andreas Huber            "audio_decoder.vorbis", "audio_encoder.vorbis" },
1081bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian        { MEDIA_MIMETYPE_AUDIO_OPUS,
1082bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian            "audio_decoder.opus", "audio_encoder.opus" },
1083c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_MLAW,
1084c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" },
1085c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_ALAW,
1086c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711alaw", "audio_encoder.g711alaw" },
1087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_AVC,
1088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.avc", "video_encoder.avc" },
10892472b1c0d63454e5d90a982bd6c555de6c3127bdRachad        { MEDIA_MIMETYPE_VIDEO_HEVC,
10902472b1c0d63454e5d90a982bd6c555de6c3127bdRachad            "video_decoder.hevc", "video_encoder.hevc" },
1091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_MPEG4,
1092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.mpeg4", "video_encoder.mpeg4" },
1093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_H263,
1094f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.h263", "video_encoder.h263" },
109594705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP8,
109694705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp8", "video_encoder.vp8" },
109794705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP9,
109894705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp9", "video_encoder.vp9" },
1099ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        { MEDIA_MIMETYPE_AUDIO_RAW,
1100ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            "audio_decoder.raw", "audio_encoder.raw" },
11012f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        { MEDIA_MIMETYPE_AUDIO_FLAC,
11022f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            "audio_decoder.flac", "audio_encoder.flac" },
1103ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        { MEDIA_MIMETYPE_AUDIO_MSGSM,
1104ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen            "audio_decoder.gsm", "audio_encoder.gsm" },
1105774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu        { MEDIA_MIMETYPE_VIDEO_MPEG2,
1106774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu            "video_decoder.mpeg2", "video_encoder.mpeg2" },
110797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        { MEDIA_MIMETYPE_AUDIO_AC3,
110897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            "audio_decoder.ac3", "audio_encoder.ac3" },
1109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
1110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const size_t kNumMimeToRole =
1112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
1113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    size_t i;
1115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (i = 0; i < kNumMimeToRole; ++i) {
1116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcasecmp(mime, kMimeToRole[i].mime)) {
1117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (i == kNumMimeToRole) {
11225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_UNSUPPORTED;
1123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    const char *role =
1126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        isEncoder ? kMimeToRole[i].encoderRole
1127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                  : kMimeToRole[i].decoderRole;
1128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (role != NULL) {
1130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_PARAM_COMPONENTROLETYPE roleParams;
1131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        InitOMXParams(&roleParams);
1132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        strncpy((char *)roleParams.cRole,
1134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                role, OMX_MAX_STRINGNAME_SIZE - 1);
1135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
1137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->setParameter(
1139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamStandardComponentRole,
1140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &roleParams, sizeof(roleParams));
1141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
11435ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("[%s] Failed to set standard component role '%s'.",
1144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 mComponentName.c_str(), role);
11455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
1147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
11495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
1151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
11535778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::configureCodec(
1154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime, const sp<AMessage> &msg) {
11555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t encoder;
11565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("encoder", &encoder)) {
11575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        encoder = false;
11585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1160e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    sp<AMessage> inputFormat = new AMessage();
1161e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    sp<AMessage> outputFormat = new AMessage();
1162e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
11635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mIsEncoder = encoder;
1164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
11655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setComponentRole(encoder /* isEncoder */, mime);
11665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
11685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
11695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
11705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitRate = 0;
11722f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    // FLAC encoder doesn't need a bitrate, other encoders do
11732f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
11742f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            && !msg->findInt32("bitrate", &bitRate)) {
11755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
11765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
11775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1178d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    int32_t storeMeta;
1179d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (encoder
1180d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && msg->findInt32("store-metadata-in-buffers", &storeMeta)
1181d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && storeMeta != 0) {
1182d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE);
1183d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1184d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (err != OK) {
1185308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              ALOGE("[%s] storeMetaDataInBuffers (input) failed w/ err %d",
1186308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    mComponentName.c_str(), err);
1187d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1188308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              return err;
1189308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang          }
1190308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang      }
1191d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1192308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t prependSPSPPS = 0;
11933a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    if (encoder
11943a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
11953a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && prependSPSPPS != 0) {
11963a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        OMX_INDEXTYPE index;
11973a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        err = mOMX->getExtensionIndex(
11983a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                mNode,
11993a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                "OMX.google.android.index.prependSPSPPSToIDRFrames",
12003a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                &index);
12013a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
12023a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err == OK) {
12033a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            PrependSPSPPSToIDRFramesParams params;
12043a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            InitOMXParams(&params);
12053a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            params.bEnable = OMX_TRUE;
12063a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
12073a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            err = mOMX->setParameter(
12083a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                    mNode, index, &params, sizeof(params));
12093a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
12103a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
12113a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err != OK) {
12123a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            ALOGE("Encoder could not be configured to emit SPS/PPS before "
12133a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                  "IDR frames. (err %d)", err);
12143a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
12153a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            return err;
12163a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
12173a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    }
12183a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
1219308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // Only enable metadata mode on encoder output if encoder can prepend
1220308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // sps/pps to idr frames, since in metadata mode the bitstream is in an
1221308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // opaque handle, to which we don't have access.
1222308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t video = !strncasecmp(mime, "video/", 6);
1223308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (encoder && video) {
1224308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS
1225308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && msg->findInt32("store-metadata-in-buffers-output", &storeMeta)
1226308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && storeMeta != 0);
1227308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1228308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, enable);
1229308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1230308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        if (err != OK) {
1231308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            ALOGE("[%s] storeMetaDataInBuffers (output) failed w/ err %d",
1232308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                mComponentName.c_str(), err);
1233308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = 0;
1234308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        } else {
1235308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = enable;
1236308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        }
1237a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
1238a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (!msg->findInt64(
1239a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    "repeat-previous-frame-after",
1240a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    &mRepeatFrameDelayUs)) {
1241a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            mRepeatFrameDelayUs = -1ll;
1242a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
124394ee4b708acfa941581160b267afb79192b1d816Chong Zhang
124494ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (!msg->findInt64("max-pts-gap-to-encoder", &mMaxPtsGapUs)) {
12452c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mMaxPtsGapUs = -1ll;
12462c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
12472c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
12482c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (!msg->findInt64("time-lapse", &mTimePerCaptureUs)) {
12492c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mTimePerCaptureUs = -1ll;
125094ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
125172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
125272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (!msg->findInt32(
125372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    "create-input-buffers-suspended",
125472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    (int32_t*)&mCreateInputBuffersSuspended)) {
125572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mCreateInputBuffersSuspended = false;
125672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
1257308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    }
1258308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1259054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    sp<RefBase> obj;
1260054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    int32_t haveNativeWindow = msg->findObject("native-window", &obj) &&
12615a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        obj != NULL;
1262054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mStoreMetaDataInOutputBuffers = false;
1263e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if (video && !encoder) {
1264e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        inputFormat->setInt32("adaptive-playback", false);
1265e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
1266054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (!encoder && video && haveNativeWindow) {
12675a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        sp<NativeWindowWrapper> windowWrapper(
12685a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                static_cast<NativeWindowWrapper *>(obj.get()));
12695a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        sp<ANativeWindow> nativeWindow = windowWrapper->getNativeWindow();
12705a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
12715a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        int32_t tunneled;
12725a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        if (msg->findInt32("feature-tunneled-playback", &tunneled) &&
12735a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            tunneled != 0) {
12745a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            ALOGI("Configuring TUNNELED video playback.");
1275ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            mTunneled = true;
12765a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
127797827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad            int32_t audioHwSync = 0;
127897827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad            if (!msg->findInt32("audio-hw-sync", &audioHwSync)) {
12795a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGW("No Audio HW Sync provided for video tunnel");
12805a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            }
12815a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            err = configureTunneledVideoPlayback(audioHwSync, nativeWindow);
12825a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (err != OK) {
128397827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad                ALOGE("configureTunneledVideoPlayback(%d,%p) failed!",
12845a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        audioHwSync, nativeWindow.get());
12855a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                return err;
1286fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
1287fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
12885a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            inputFormat->setInt32("adaptive-playback", true);
12895a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        } else {
1290ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            ALOGV("Configuring CPU controlled video playback.");
1291ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            mTunneled = false;
1292ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
12935a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            // Always try to enable dynamic output buffers on native surface
12945a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            err = mOMX->storeMetaDataInBuffers(
12955a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    mNode, kPortIndexOutput, OMX_TRUE);
12965a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (err != OK) {
12975a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d",
1298fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        mComponentName.c_str(), err);
1299e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
13005a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // if adaptive playback has been requested, try JB fallback
13015a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // NOTE: THIS FALLBACK MECHANISM WILL BE REMOVED DUE TO ITS
13025a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // LARGE MEMORY REQUIREMENT
13035a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
13045a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // we will not do adaptive playback on software accessed
13055a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // surfaces as they never had to respond to changes in the
13065a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // crop window, and we don't trust that they will be able to.
13075a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                int usageBits = 0;
13085a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                bool canDoAdaptivePlayback;
13095a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
13105a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                if (nativeWindow->query(
13115a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        nativeWindow.get(),
13125a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        NATIVE_WINDOW_CONSUMER_USAGE_BITS,
13135a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        &usageBits) != OK) {
13145a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    canDoAdaptivePlayback = false;
13155a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                } else {
13165a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    canDoAdaptivePlayback =
13175a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        (usageBits &
13185a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                                (GRALLOC_USAGE_SW_READ_MASK |
13195a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                                 GRALLOC_USAGE_SW_WRITE_MASK)) == 0;
13205a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                }
13215a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
13225a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                int32_t maxWidth = 0, maxHeight = 0;
13235a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                if (canDoAdaptivePlayback &&
13245a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        msg->findInt32("max-width", &maxWidth) &&
13255a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        msg->findInt32("max-height", &maxHeight)) {
13265a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    ALOGV("[%s] prepareForAdaptivePlayback(%dx%d)",
13275a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mComponentName.c_str(), maxWidth, maxHeight);
13285a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
13295a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    err = mOMX->prepareForAdaptivePlayback(
13305a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mNode, kPortIndexOutput, OMX_TRUE, maxWidth,
13315a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            maxHeight);
13325a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    ALOGW_IF(err != OK,
13335a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            "[%s] prepareForAdaptivePlayback failed w/ err %d",
13345a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mComponentName.c_str(), err);
13355a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
13365a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    if (err == OK) {
13375a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("max-width", maxWidth);
13385a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("max-height", maxHeight);
13395a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("adaptive-playback", true);
13405a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    }
1341e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
13425a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // allow failure
13435a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                err = OK;
13445a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            } else {
13455a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGV("[%s] storeMetaDataInBuffers succeeded",
13465a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        mComponentName.c_str());
13475a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                mStoreMetaDataInOutputBuffers = true;
13485a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                inputFormat->setInt32("adaptive-playback", true);
1349fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
13500167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber
13515a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            int32_t push;
13525a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (msg->findInt32("push-blank-buffers-on-shutdown", &push)
13535a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    && push != 0) {
13545a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
13555a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            }
13560167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        }
1357e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang
1358e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        int32_t rotationDegrees;
1359e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        if (msg->findInt32("rotation-degrees", &rotationDegrees)) {
1360e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            mRotationDegrees = rotationDegrees;
1361e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        } else {
1362e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            mRotationDegrees = 0;
1363e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        }
1364054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1365054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1366308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (video) {
13675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (encoder) {
13685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupVideoEncoder(mime, msg);
13695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
137089869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            err = setupVideoDecoder(mime, msg);
13715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
137242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
137342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        int32_t numChannels, sampleRate;
137442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        if (!msg->findInt32("channel-count", &numChannels)
137542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
137642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // Since we did not always check for these, leave them optional
137742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // and have the decoder figure it all out.
137842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = OK;
137942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        } else {
138042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = setupRawAudioFormat(
138142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    encoder ? kPortIndexInput : kPortIndexOutput,
138242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    sampleRate,
138342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    numChannels);
138442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        }
1385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
1386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t numChannels, sampleRate;
13875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)
13885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
13895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
13905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
1391aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            int32_t isADTS, aacProfile;
1392b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            int32_t sbrMode;
13938045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            int32_t maxOutputChannelCount;
13942965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            int32_t pcmLimiterEnable;
13958045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            drcParams_t drc;
1396ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            if (!msg->findInt32("is-adts", &isADTS)) {
1397ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                isADTS = 0;
1398ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
1399aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (!msg->findInt32("aac-profile", &aacProfile)) {
1400aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                aacProfile = OMX_AUDIO_AACObjectNull;
1401aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
1402b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            if (!msg->findInt32("aac-sbr-mode", &sbrMode)) {
1403b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                sbrMode = -1;
1404b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            }
1405ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
14068045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-max-output-channel_count", &maxOutputChannelCount)) {
14078045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                maxOutputChannelCount = -1;
14088045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
14092965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            if (!msg->findInt32("aac-pcm-limiter-enable", &pcmLimiterEnable)) {
14102965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                // value is unknown
14112965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                pcmLimiterEnable = -1;
14122965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            }
14138045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-encoded-target-level", &drc.encodedTargetLevel)) {
14148045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
14158045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.encodedTargetLevel = -1;
14168045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
14178045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-cut-level", &drc.drcCut)) {
14188045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
14198045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.drcCut = -1;
14208045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
14218045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-boost-level", &drc.drcBoost)) {
14228045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
14238045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.drcBoost = -1;
14248045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
14258045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-heavy-compression", &drc.heavyCompression)) {
14268045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
14278045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.heavyCompression = -1;
14288045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
14298045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-target-ref-level", &drc.targetRefLevel)) {
14308045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
14318045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.targetRefLevel = -1;
14328045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
14338045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi
1434ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            err = setupAACCodec(
14354471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    encoder, numChannels, sampleRate, bitRate, aacProfile,
14362965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                    isADTS != 0, sbrMode, maxOutputChannelCount, drc,
14372965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                    pcmLimiterEnable);
14385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
1439729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
14405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
1441729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
14425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
1443729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
1444729de186450f78c099637e1fce743fe531862c52Andreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
1445729de186450f78c099637e1fce743fe531862c52Andreas Huber        // These are PCM-like formats with a fixed sample rate but
1446729de186450f78c099637e1fce743fe531862c52Andreas Huber        // a variable number of channels.
1447729de186450f78c099637e1fce743fe531862c52Andreas Huber
1448729de186450f78c099637e1fce743fe531862c52Andreas Huber        int32_t numChannels;
14495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)) {
14505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
14515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
14525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupG711Codec(encoder, numChannels);
14535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14542f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
14552f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        int32_t numChannels, sampleRate, compressionLevel = -1;
14562f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (encoder &&
14572f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                (!msg->findInt32("channel-count", &numChannels)
14582f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                        || !msg->findInt32("sample-rate", &sampleRate))) {
14592f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("missing channel count or sample rate for FLAC encoder");
14602f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            err = INVALID_OPERATION;
14612f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        } else {
14622f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            if (encoder) {
1463516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                if (!msg->findInt32(
1464cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                            "complexity", &compressionLevel) &&
1465cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                    !msg->findInt32(
1466516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                            "flac-compression-level", &compressionLevel)) {
1467cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                    compressionLevel = 5; // default FLAC compression level
14682f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel < 0) {
1469516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1470516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 0",
1471516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
14722f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 0;
14732f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel > 8) {
1474516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1475516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 8",
1476516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
14772f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 8;
14782f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                }
14792f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            }
1480516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            err = setupFlacCodec(
1481516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    encoder, numChannels, sampleRate, compressionLevel);
14822f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
1483ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
1484ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        int32_t numChannels, sampleRate;
1485ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        if (encoder
1486ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("channel-count", &numChannels)
1487ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
1488ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = INVALID_OPERATION;
1489ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        } else {
1490ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
1491ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        }
149297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AC3)) {
149397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t numChannels;
149497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t sampleRate;
149597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        if (!msg->findInt32("channel-count", &numChannels)
149697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                || !msg->findInt32("sample-rate", &sampleRate)) {
149797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = INVALID_OPERATION;
149897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        } else {
149997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = setupAC3Codec(encoder, numChannels, sampleRate);
150097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        }
15015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1502729de186450f78c099637e1fce743fe531862c52Andreas Huber
15034471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    if (err != OK) {
15044471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber        return err;
15054471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    }
15064471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber
15078b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
15088b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderDelay = 0;
15098b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
15109806555d3930be43e11106281dee354820ac1c88Andreas Huber
15118b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
15128b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderPadding = 0;
15138b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
15148b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen
15159806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (msg->findInt32("channel-mask", &mChannelMask)) {
15169806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = true;
15179806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else {
15189806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = false;
15199806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
15209806555d3930be43e11106281dee354820ac1c88Andreas Huber
1521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t maxInputSize;
1522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (msg->findInt32("max-input-size", &maxInputSize)) {
15235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
1524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
15255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
1526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
15275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1528e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ(getPortFormat(kPortIndexInput, inputFormat), (status_t)OK);
1529e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ(getPortFormat(kPortIndexOutput, outputFormat), (status_t)OK);
1530e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mInputFormat = inputFormat;
1531e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mOutputFormat = outputFormat;
1532e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
15335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
1534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1536f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
1537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
1539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
1540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (def.nBufferSize >= size) {
1549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
1550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nBufferSize = size;
1553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
1555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->getParameter(
1562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(def.nBufferSize >= size);
1569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
15735778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::selectAudioPortFormat(
15745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
15755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_AUDIO_PARAM_PORTFORMATTYPE format;
15765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&format);
15775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    format.nPortIndex = portIndex;
15795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (OMX_U32 index = 0;; ++index) {
15805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        format.nIndex = index;
15815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
15835778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioPortFormat,
15845778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &format, sizeof(format));
15855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
15875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
15885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (format.eEncoding == desiredFormat) {
15915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
15925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
15965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format));
15975778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
15985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15995778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAACCodec(
1600aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        bool encoder, int32_t numChannels, int32_t sampleRate,
16018045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        int32_t bitRate, int32_t aacProfile, bool isADTS, int32_t sbrMode,
16022965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang        int32_t maxOutputChannelCount, const drcParams_t& drc,
16032965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang        int32_t pcmLimiterEnable) {
1604ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (encoder && isADTS) {
1605ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return -EINVAL;
1606ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
1607ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
16085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setupRawAudioFormat(
16095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
16105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sampleRate,
16115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            numChannels);
16125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
16145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
16155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (encoder) {
16185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
16195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
16215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
16225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
16255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
16265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = kPortIndexOutput;
16275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
16295778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
16305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
16325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
16335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.bFlagErrorConcealment = OMX_TRUE;
16365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
16375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
16395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
16405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
16425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
16435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
16465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&profile);
16475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nPortIndex = kPortIndexOutput;
16485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
16505778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
16515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
16535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
16545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nChannels = numChannels;
16575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eChannelMode =
16595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (numChannels == 1)
16605778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
16615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nSampleRate = sampleRate;
16635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nBitRate = bitRate;
16645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAudioBandWidth = 0;
16655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nFrameLength = 0;
16665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACtools = OMX_AUDIO_AACToolAll;
16675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACERtools = OMX_AUDIO_AACERNone;
1668aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
16695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
1670b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        switch (sbrMode) {
1671b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 0:
1672b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // disable sbr
1673b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
1674b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
1675b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
1676b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 1:
1677b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable single-rate sbr
1678b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
1679b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
1680b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
1681b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 2:
1682b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable dual-rate sbr
1683b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
1684b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
1685b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
1686b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case -1:
1687b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable both modes -> the codec will decide which mode should be used
1688b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
1689b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
1690b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
1691b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        default:
1692b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // unsupported sbr mode
1693b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            return BAD_VALUE;
1694b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        }
1695b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi
16965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
16985778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
16995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
17015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
17025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
17055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_AUDIO_PARAM_AACPROFILETYPE profile;
1708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&profile);
1709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nPortIndex = kPortIndexInput;
1710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
17115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
1712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
1713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nChannels = numChannels;
1719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nSampleRate = sampleRate;
1720ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1721ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    profile.eAACStreamFormat =
1722ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        isADTS
1723ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            ? OMX_AUDIO_AACStreamFormatMP4ADTS
1724ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            : OMX_AUDIO_AACStreamFormatMP4FF;
1725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
17268045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    OMX_AUDIO_PARAM_ANDROID_AACPRESENTATIONTYPE presentation;
17278045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nMaxOutputChannels = maxOutputChannelCount;
17288045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nDrcCut = drc.drcCut;
17298045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nDrcBoost = drc.drcBoost;
17308045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nHeavyCompression = drc.heavyCompression;
17318045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nTargetReferenceLevel = drc.targetRefLevel;
17328045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nEncodedTargetLevel = drc.encodedTargetLevel;
17332965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang    presentation.nPCMLimiterEnable = pcmLimiterEnable;
17348045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi
17358045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    status_t res = mOMX->setParameter(mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
17368045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    if (res == OK) {
17378045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        // optional parameters, will not cause configuration failure
17388045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        mOMX->setParameter(mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAacPresentation,
17398045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                &presentation, sizeof(presentation));
17408045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    } else {
17418045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        ALOGW("did not set AudioAndroidAacPresentation due to error %d when setting AudioAac", res);
17428045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    }
17438045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    return res;
17445778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
174697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryustatus_t ACodec::setupAC3Codec(
174797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        bool encoder, int32_t numChannels, int32_t sampleRate) {
174897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    status_t err = setupRawAudioFormat(
174997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
175097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
175197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
175297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
175397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
175497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
175597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (encoder) {
175697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        ALOGW("AC3 encoding is not supported.");
175797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return INVALID_OPERATION;
175897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
175997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
176097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    OMX_AUDIO_PARAM_ANDROID_AC3TYPE def;
176197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    InitOMXParams(&def);
176297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nPortIndex = kPortIndexInput;
176397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
176497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    err = mOMX->getParameter(
176597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
176697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
176797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
176897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
176997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
177097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
177197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
177297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
177397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
177497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nChannels = numChannels;
177597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nSampleRate = sampleRate;
177697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
177797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    return mOMX->setParameter(
177897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
177997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
178097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
178197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
178297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu}
178397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
17845778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
17855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        bool isAMRWB, int32_t bps) {
17865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (isAMRWB) {
17875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 6600) {
17885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB0;
17895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 8850) {
17905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB1;
17915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 12650) {
17925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB2;
17935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 14250) {
17945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB3;
17955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 15850) {
17965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB4;
17975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 18250) {
17985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB5;
17995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 19850) {
18005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB6;
18015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 23050) {
18025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB7;
18035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 23850 bps
18065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeWB8;
18075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {  // AMRNB
18085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 4750) {
18095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB0;
18105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5150) {
18115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB1;
18125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5900) {
18135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB2;
18145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 6700) {
18155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB3;
18165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7400) {
18175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB4;
18185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7950) {
18195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB5;
18205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 10200) {
18215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB6;
18225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 12200 bps
18255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeNB7;
18265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
18295778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
1830729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_AMRTYPE def;
1831729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
18325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
1833729de186450f78c099637e1fce743fe531862c52Andreas Huber
1834729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err =
1835729de186450f78c099637e1fce743fe531862c52Andreas Huber        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1836729de186450f78c099637e1fce743fe531862c52Andreas Huber
1837729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1838729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1839729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1840729de186450f78c099637e1fce743fe531862c52Andreas Huber
1841729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
18425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
18435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
18455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1846729de186450f78c099637e1fce743fe531862c52Andreas Huber
18475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1850729de186450f78c099637e1fce743fe531862c52Andreas Huber
18515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupRawAudioFormat(
18525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
18535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            isWAMR ? 16000 : 8000 /* sampleRate */,
18545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            1 /* numChannels */);
1855729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1856729de186450f78c099637e1fce743fe531862c52Andreas Huber
18575778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupG711Codec(bool encoder, int32_t numChannels) {
18585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(!encoder);  // XXX TODO
18595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1860729de186450f78c099637e1fce743fe531862c52Andreas Huber    return setupRawAudioFormat(
1861729de186450f78c099637e1fce743fe531862c52Andreas Huber            kPortIndexInput, 8000 /* sampleRate */, numChannels);
1862729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1863729de186450f78c099637e1fce743fe531862c52Andreas Huber
18642f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivistatus_t ACodec::setupFlacCodec(
18652f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
18662f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
18672f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder) {
18682f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        OMX_AUDIO_PARAM_FLACTYPE def;
18692f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        InitOMXParams(&def);
18702f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nPortIndex = kPortIndexOutput;
18712f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
18722f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        // configure compression level
18732f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        status_t err = mOMX->getParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
18742f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
18752f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
18762f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
18772f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
18782f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nCompressionLevel = compressionLevel;
18792f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        err = mOMX->setParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
18802f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
18812f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
18822f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
18832f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
18842f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
18852f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
18862f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    return setupRawAudioFormat(
18872f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            encoder ? kPortIndexInput : kPortIndexOutput,
18882f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            sampleRate,
18892f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            numChannels);
18902f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi}
18912f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
1892729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t ACodec::setupRawAudioFormat(
1893729de186450f78c099637e1fce743fe531862c52Andreas Huber        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
1894729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1895729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
1896729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.nPortIndex = portIndex;
1897729de186450f78c099637e1fce743fe531862c52Andreas Huber
1898729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err = mOMX->getParameter(
1899729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1900729de186450f78c099637e1fce743fe531862c52Andreas Huber
1901729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1902729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1903729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1904729de186450f78c099637e1fce743fe531862c52Andreas Huber
1905729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
1906729de186450f78c099637e1fce743fe531862c52Andreas Huber
1907729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->setParameter(
1908729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1909729de186450f78c099637e1fce743fe531862c52Andreas Huber
1910729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1911729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1912729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1913729de186450f78c099637e1fce743fe531862c52Andreas Huber
1914729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
1915729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&pcmParams);
1916729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nPortIndex = portIndex;
1917729de186450f78c099637e1fce743fe531862c52Andreas Huber
1918729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->getParameter(
1919729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1920729de186450f78c099637e1fce743fe531862c52Andreas Huber
1921729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1922729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1923729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1924729de186450f78c099637e1fce743fe531862c52Andreas Huber
1925729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nChannels = numChannels;
1926729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.eNumData = OMX_NumericalDataSigned;
1927729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.bInterleaved = OMX_TRUE;
1928729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nBitPerSample = 16;
1929729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nSamplingRate = sampleRate;
1930729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
1931729de186450f78c099637e1fce743fe531862c52Andreas Huber
1932c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber    if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
1933c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber        return OMX_ErrorNone;
1934729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1935729de186450f78c099637e1fce743fe531862c52Andreas Huber
1936729de186450f78c099637e1fce743fe531862c52Andreas Huber    return mOMX->setParameter(
1937729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1938729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1939729de186450f78c099637e1fce743fe531862c52Andreas Huber
19405a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachadstatus_t ACodec::configureTunneledVideoPlayback(
194197827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad        int32_t audioHwSync, const sp<ANativeWindow> &nativeWindow) {
19425a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    native_handle_t* sidebandHandle;
19435a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
19445a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    status_t err = mOMX->configureVideoTunnelMode(
19455a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            mNode, kPortIndexOutput, OMX_TRUE, audioHwSync, &sidebandHandle);
19465a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    if (err != OK) {
19475a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        ALOGE("configureVideoTunnelMode failed! (err %d).", err);
19485a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        return err;
19495a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    }
19505a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
19515a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    err = native_window_set_sideband_stream(nativeWindow.get(), sidebandHandle);
19525a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    if (err != OK) {
19535a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        ALOGE("native_window_set_sideband_stream(%p) failed! (err %d).",
19545a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                sidebandHandle, err);
19555a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        return err;
19565a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    }
19575a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
19585a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    return OK;
19595a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad}
19605a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
1961f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoPortFormatType(
1962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
1963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_VIDEO_CODINGTYPE compressionFormat,
1964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_COLOR_FORMATTYPE colorFormat) {
1965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
1967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = portIndex;
1968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
1969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool found = false;
1970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 index = 0;
1972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (;;) {
1973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        format.nIndex = index;
1974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->getParameter(
1975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamVideoPortFormat,
1976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &format, sizeof(format));
1977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
1979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return err;
1980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1982229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        // substitute back flexible color format to codec supported format
1983229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        OMX_U32 flexibleEquivalent;
1984229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        if (compressionFormat == OMX_VIDEO_CodingUnused &&
1985229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                isFlexibleColorFormat(
1986229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                        mOMX, mNode, format.eColorFormat, &flexibleEquivalent) &&
1987229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                colorFormat == flexibleEquivalent) {
1988229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            ALOGI("[%s] using color format %#x in place of %#x",
1989229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                    mComponentName.c_str(), format.eColorFormat, colorFormat);
1990229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            colorFormat = format.eColorFormat;
1991229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
1992229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
1993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The following assertion is violated by TI's video decoder.
1994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // CHECK_EQ(format.nIndex, index);
1995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
1997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexInput
1998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && colorFormat == format.eColorFormat) {
1999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eCompressionFormat does not seem right.
2000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
2001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
2002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexOutput
2004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && compressionFormat == format.eCompressionFormat) {
2005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eColorFormat does not seem right.
2006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
2007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
2008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (format.eCompressionFormat == compressionFormat
2012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && format.eColorFormat == colorFormat) {
2013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            found = true;
2014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ++index;
2018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!found) {
2021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return UNKNOWN_ERROR;
2022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->setParameter(
2025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
2026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
2027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
2029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2031f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setSupportedOutputFormat() {
2032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
2033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
2034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = kPortIndexOutput;
2035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
2036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
2038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
2039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
2040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
2041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)format.eCompressionFormat, (int)OMX_VIDEO_CodingUnused);
2042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mOMX->setParameter(
2044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
2045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
2046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2048e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic const struct VideoCodingMapEntry {
2049e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    const char *mMime;
2050e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    OMX_VIDEO_CODINGTYPE mVideoCodingType;
2051e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber} kVideoCodingMapEntry[] = {
2052e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC },
20532472b1c0d63454e5d90a982bd6c555de6c3127bdRachad    { MEDIA_MIMETYPE_VIDEO_HEVC, OMX_VIDEO_CodingHEVC },
2054e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 },
2055e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 },
2056e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 },
205794705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 },
205894705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 },
2059e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber};
2060e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
20615778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic status_t GetVideoCodingTypeFromMime(
20625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
2063e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
2064e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
2065e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
2066e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) {
2067e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *codingType = kVideoCodingMapEntry[i].mVideoCodingType;
2068e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
2069e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
2070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2072e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    *codingType = OMX_VIDEO_CodingUnused;
2073e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2074e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
2075e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
2076e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2077e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic status_t GetMimeTypeForVideoCoding(
2078e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        OMX_VIDEO_CODINGTYPE codingType, AString *mime) {
2079e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
2080e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
2081e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
2082e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) {
2083e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *mime = kVideoCodingMapEntry[i].mMime;
2084e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
2085e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
2086e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
2087e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2088e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    mime->clear();
2089e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2090e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
20915778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
20925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20935778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoDecoder(
209489869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        const char *mime, const sp<AMessage> &msg) {
209589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    int32_t width, height;
209689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    if (!msg->findInt32("width", &width)
209789869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            || !msg->findInt32("height", &height)) {
209889869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        return INVALID_OPERATION;
209989869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    }
210089869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar
21015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
21025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
21035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
2109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
2110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
211589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    int32_t tmp;
211689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    if (msg->findInt32("color-format", &tmp)) {
211789869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        OMX_COLOR_FORMATTYPE colorFormat =
211889869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            static_cast<OMX_COLOR_FORMATTYPE>(tmp);
211989869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        err = setVideoPortFormatType(
212089869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar                kPortIndexOutput, OMX_VIDEO_CodingUnused, colorFormat);
212189869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        if (err != OK) {
212289869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            ALOGW("[%s] does not support color format %d",
212389869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar                  mComponentName.c_str(), colorFormat);
212489869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            err = setSupportedOutputFormat();
212589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        }
212689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    } else {
212789869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        err = setSupportedOutputFormat();
212889869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    }
2129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
2135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, width, height, compressionFormat);
2136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
2142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
2143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
21515778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) {
21525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
21535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("color-format", &tmp)) {
21545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
21555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_COLOR_FORMATTYPE colorFormat =
21585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        static_cast<OMX_COLOR_FORMATTYPE>(tmp);
21595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setVideoPortFormatType(
21615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
21625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support color format %d",
21655778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str(), colorFormat);
21665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Input port configuration */
21715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
21735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&def);
21745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
21765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexInput;
21785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
21805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
21815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t width, height, bitrate;
21875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("width", &width)
21885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("height", &height)
21895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("bitrate", &bitrate)) {
21905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
21915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
21945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
21955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t stride;
21975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("stride", &stride)) {
21985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        stride = width;
21995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nStride = stride;
22025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t sliceHeight;
22045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("slice-height", &sliceHeight)) {
22055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sliceHeight = height;
22065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nSliceHeight = sliceHeight;
22095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
22115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
22135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
22145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
22155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
22165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
22175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
22192c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        mTimePerFrameUs = (int64_t) (1000000.0f / frameRate);
22205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
22235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
22245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = colorFormat;
22255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
22275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
22285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set input port definition parameters.",
22315778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
22325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Output port configuration */
22375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
22395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
22405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
22465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
22475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support compression format %d",
22505778822d86b0337407514b9372562b86edfa91cdAndreas Huber             mComponentName.c_str(), compressionFormat);
22515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexOutput;
22565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
22585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
22595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
22655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
22665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = 0;
22675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nBitrate = bitrate;
22685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = compressionFormat;
22695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = OMX_COLOR_FormatUnused;
22705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
22725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
22735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set output port definition parameters.",
22765778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
22775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (compressionFormat) {
22825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingMPEG4:
22835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupMPEG4EncoderParameters(msg);
22845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
22855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingH263:
22875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupH263EncoderParameters(msg);
22885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
22895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingAVC:
22915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupAVCEncoderParameters(msg);
22925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
22935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2294c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        case OMX_VIDEO_CodingHEVC:
2295c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            err = setupHEVCEncoderParameters(msg);
2296c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            break;
2297c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
229889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP8:
229989b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP9:
230089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            err = setupVPXEncoderParameters(msg);
230189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            break;
230289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
23035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
23045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
23055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGI("setupVideoEncoder succeeded");
23085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
23105778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
23115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23120dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dongstatus_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) {
23130dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    OMX_VIDEO_PARAM_INTRAREFRESHTYPE params;
23140dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    InitOMXParams(&params);
23150dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.nPortIndex = kPortIndexOutput;
23160dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
23170dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode);
23180dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
23190dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic ||
23200dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
23210dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
23220dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) {
23230dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
23240dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
23250dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nCirMBs = mbs;
23260dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
23270dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
23280dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive ||
23290dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
23300dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
23310dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) {
23320dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
23330dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
23340dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirMBs = mbs;
23350dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
23360dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t ref;
23370dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) {
23380dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
23390dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
23400dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirRef = ref;
23410dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
23420dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
23430dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = mOMX->setParameter(
23440dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            mNode, OMX_IndexParamVideoIntraRefresh,
23450dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            &params, sizeof(params));
23460dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    return err;
23470dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong}
23480dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
23495778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
23505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (iFramesInterval < 0) {
23515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0xFFFFFFFF;
23525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (iFramesInterval == 0) {
23535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0;
23545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_U32 ret = frameRate * iFramesInterval;
23565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return ret;
23575778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
23585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
235996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatic OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) {
236096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    int32_t tmp;
236196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    if (!msg->findInt32("bitrate-mode", &tmp)) {
236296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        return OMX_Video_ControlRateVariable;
236396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    }
236496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
236596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp);
236696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber}
236796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
23685778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
23695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
23705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
23715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
23725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
23735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
237596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
237696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
23775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
23785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
23795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
23805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
23815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
23825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
23845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
23875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&mpeg4type);
23885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPortIndex = kPortIndexOutput;
23895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
23915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
23925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
23945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
23955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nSliceHeaderSpacing = 0;
23985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bSVH = OMX_FALSE;
23995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bGov = OMX_FALSE;
24005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nAllowedPictureTypes =
24025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
24035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
24055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mpeg4type.nPFrames == 0) {
24065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
24075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nBFrames = 0;
24095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nIDCVLCThreshold = 0;
24105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bACPred = OMX_TRUE;
24115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nMaxPacketSize = 256;
24125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nTimeIncRes = 1000;
24135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nHeaderExtension = 0;
24145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bReversibleVLC = OMX_FALSE;
24155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
24175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
24185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
24195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
24205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
24215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
24225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
24245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
24265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
24275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
24285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
24305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
24315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
24345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
24355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
24375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
24385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
244096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
24415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
24435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
24445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
24475778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
24485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24495778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
24505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
24515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
24525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
24535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
24545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
245696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
245796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
24585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
24595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
24605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
24615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
24625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
24635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
24645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
24655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_H263TYPE h263type;
24685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h263type);
24695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPortIndex = kPortIndexOutput;
24705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
24725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
24735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
24755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
24765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nAllowedPictureTypes =
24795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
24805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
24825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h263type.nPFrames == 0) {
24835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
24845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nBFrames = 0;
24865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
24885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
24895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
24905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
24915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
24925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
24935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
24955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
24975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
24985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
24995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
25015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
25025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bPLUSPTYPEAllowed = OMX_FALSE;
25055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bForceRoundingTypeToZero = OMX_FALSE;
25065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPictureHeaderRepetition = 0;
25075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nGOBHeaderInterval = 0;
25085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
25105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
25115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
25135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
25145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
251696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
25175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
25195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
25205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
25235778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
25245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2525a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar// static
2526a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnarint /* OMX_VIDEO_AVCLEVELTYPE */ ACodec::getAVCLevelFor(
2527a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        int width, int height, int rate, int bitrate,
2528a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        OMX_VIDEO_AVCPROFILETYPE profile) {
2529a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    // convert bitrate to main/baseline profile kbps equivalent
2530a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    switch (profile) {
2531a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        case OMX_VIDEO_AVCProfileHigh10:
2532a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 3000); break;
2533a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        case OMX_VIDEO_AVCProfileHigh:
2534a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 1250); break;
2535a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        default:
2536a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 1000); break;
2537a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    }
2538a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
2539a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    // convert size and rate to MBs
2540a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    width = divUp(width, 16);
2541a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    height = divUp(height, 16);
2542a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    int mbs = width * height;
2543a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    rate *= mbs;
2544a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    int maxDimension = max(width, height);
2545a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
2546a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    static const int limits[][5] = {
2547a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        /*   MBps     MB   dim  bitrate        level */
2548a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    1485,    99,  28,     64, OMX_VIDEO_AVCLevel1  },
2549a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    1485,    99,  28,    128, OMX_VIDEO_AVCLevel1b },
2550a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    3000,   396,  56,    192, OMX_VIDEO_AVCLevel11 },
2551a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    6000,   396,  56,    384, OMX_VIDEO_AVCLevel12 },
2552a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   11880,   396,  56,    768, OMX_VIDEO_AVCLevel13 },
2553a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   11880,   396,  56,   2000, OMX_VIDEO_AVCLevel2  },
2554a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   19800,   792,  79,   4000, OMX_VIDEO_AVCLevel21 },
2555a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   20250,  1620, 113,   4000, OMX_VIDEO_AVCLevel22 },
2556a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   40500,  1620, 113,  10000, OMX_VIDEO_AVCLevel3  },
2557a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  108000,  3600, 169,  14000, OMX_VIDEO_AVCLevel31 },
2558a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  216000,  5120, 202,  20000, OMX_VIDEO_AVCLevel32 },
2559a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  245760,  8192, 256,  20000, OMX_VIDEO_AVCLevel4  },
2560a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  245760,  8192, 256,  50000, OMX_VIDEO_AVCLevel41 },
2561a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  522240,  8704, 263,  50000, OMX_VIDEO_AVCLevel42 },
2562a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  589824, 22080, 420, 135000, OMX_VIDEO_AVCLevel5  },
2563a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  983040, 36864, 543, 240000, OMX_VIDEO_AVCLevel51 },
2564a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        { 2073600, 36864, 543, 240000, OMX_VIDEO_AVCLevel52 },
2565a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    };
2566a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
2567a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    for (size_t i = 0; i < ARRAY_SIZE(limits); i++) {
2568a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        const int (&limit)[5] = limits[i];
2569a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        if (rate <= limit[0] && mbs <= limit[1] && maxDimension <= limit[2]
2570a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar                && bitrate <= limit[3]) {
2571a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            return limit[4];
2572a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        }
2573a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    }
2574a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    return 0;
2575a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar}
2576a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
25775778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
25785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
25795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
25805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
25815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
25825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
258496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
258596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
25865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
25875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
25885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
25895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
25905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
25915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
25925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
25935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25950dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = OK;
25960dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    int32_t intraRefreshMode = 0;
25970dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) {
25980dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode);
25990dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (err != OK) {
26000dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
26010dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong                    err, intraRefreshMode);
26020dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return err;
26030dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
26040dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
26050dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
26065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_AVCTYPE h264type;
26075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h264type);
26085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nPortIndex = kPortIndexOutput;
26095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26100dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    err = mOMX->getParameter(
26115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
26125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
26145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
26155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nAllowedPictureTypes =
26185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
26195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
26215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
26225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
26235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
26245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
26255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
26265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
26285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
26305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
26315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
26325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
26345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
26355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // XXX
26387c25df82dfc8bbedb58608242f0d923a4594bb14James Dong    if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) {
26397c25df82dfc8bbedb58608242f0d923a4594bb14James Dong        ALOGW("Use baseline profile instead of %d for AVC recording",
26407c25df82dfc8bbedb58608242f0d923a4594bb14James Dong            h264type.eProfile);
26415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
26425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
26455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nSliceHeaderSpacing = 0;
26465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bUseHadamard = OMX_TRUE;
26475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefFrames = 1;
26485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nBFrames = 0;
26495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
26505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (h264type.nPFrames == 0) {
26515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
26525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
26535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx10ActiveMinus1 = 0;
26545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx11ActiveMinus1 = 0;
26555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bEntropyCodingCABAC = OMX_FALSE;
26565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bWeightedPPrediction = OMX_FALSE;
26575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bconstIpred = OMX_FALSE;
26585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirect8x8Inference = OMX_FALSE;
26595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirectSpatialTemporal = OMX_FALSE;
26605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nCabacInitIdc = 0;
26615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.nBFrames != 0) {
26645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
26655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableUEP = OMX_FALSE;
26685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableFMO = OMX_FALSE;
26695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableASO = OMX_FALSE;
26705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableRS = OMX_FALSE;
26715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bFrameMBsOnly = OMX_TRUE;
26725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bMBAFF = OMX_FALSE;
26735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
26745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
26765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
26775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
26795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
26805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
268296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return configureBitrate(bitrate, bitrateMode);
26835778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
26845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2685c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachadstatus_t ACodec::setupHEVCEncoderParameters(const sp<AMessage> &msg) {
2686c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    int32_t bitrate, iFrameInterval;
2687c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findInt32("bitrate", &bitrate)
2688c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
2689c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return INVALID_OPERATION;
2690c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2691c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2692c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
2693c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2694c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    float frameRate;
2695c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findFloat("frame-rate", &frameRate)) {
2696c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t tmp;
2697c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("frame-rate", &tmp)) {
2698c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
2699c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
2700c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        frameRate = (float)tmp;
2701c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2702c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2703c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_PARAM_HEVCTYPE hevcType;
2704c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    InitOMXParams(&hevcType);
2705c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    hevcType.nPortIndex = kPortIndexOutput;
2706c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2707c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    status_t err = OK;
2708c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    err = mOMX->getParameter(
2709c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
2710c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
2711c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
2712c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2713c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2714c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    int32_t profile;
2715c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (msg->findInt32("profile", &profile)) {
2716c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t level;
2717c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("level", &level)) {
2718c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
2719c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
2720c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2721c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        err = verifySupportForProfileAndLevel(profile, level);
2722c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (err != OK) {
2723c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return err;
2724c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
2725c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2726c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eProfile = static_cast<OMX_VIDEO_HEVCPROFILETYPE>(profile);
2727c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eLevel = static_cast<OMX_VIDEO_HEVCLEVELTYPE>(level);
2728c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2729c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2730c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    // TODO: Need OMX structure definition for setting iFrameInterval
2731c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2732c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    err = mOMX->setParameter(
2733c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
2734c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
2735c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
2736c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2737c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2738c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    return configureBitrate(bitrate, bitrateMode);
2739c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad}
2740c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
274189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huberstatus_t ACodec::setupVPXEncoderParameters(const sp<AMessage> &msg) {
274289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    int32_t bitrate;
27434154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    int32_t iFrameInterval = 0;
27444154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    size_t tsLayers = 0;
27454154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE pattern =
27464154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        OMX_VIDEO_VPXTemporalLayerPatternNone;
27474154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    static const uint32_t kVp8LayerRateAlloction
27484154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS]
27494154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS] = {
27504154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        {100, 100, 100},  // 1 layer
27514154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 60, 100, 100},  // 2 layers {60%, 40%}
27524154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 40,  60, 100},  // 3 layers {40%, 20%, 40%}
27534154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    };
275489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    if (!msg->findInt32("bitrate", &bitrate)) {
275589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        return INVALID_OPERATION;
275689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    }
27574154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    msg->findInt32("i-frame-interval", &iFrameInterval);
275889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
275989b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
276089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
27614154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    float frameRate;
27624154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (!msg->findFloat("frame-rate", &frameRate)) {
27634154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        int32_t tmp;
27644154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (!msg->findInt32("frame-rate", &tmp)) {
27654154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            return INVALID_OPERATION;
27664154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
27674154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        frameRate = (float)tmp;
27684154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
27694154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
27704154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    AString tsSchema;
27714154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (msg->findString("ts-schema", &tsSchema)) {
27724154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (tsSchema == "webrtc.vp8.1-layer") {
27734154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
27744154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 1;
27754154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else if (tsSchema == "webrtc.vp8.2-layer") {
27764154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
27774154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 2;
27784154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else if (tsSchema == "webrtc.vp8.3-layer") {
27794154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
27804154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 3;
27814154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else {
27824154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            ALOGW("Unsupported ts-schema [%s]", tsSchema.c_str());
27834154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
27844154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
27854154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
27864154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
27874154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    InitOMXParams(&vp8type);
27884154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    vp8type.nPortIndex = kPortIndexOutput;
27894154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    status_t err = mOMX->getParameter(
27904154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
27914154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            &vp8type, sizeof(vp8type));
27924154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
27934154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (err == OK) {
27944154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (iFrameInterval > 0) {
27954154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nKeyFrameInterval = setPFramesSpacing(iFrameInterval, frameRate);
27964154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
27974154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.eTemporalPattern = pattern;
27984154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.nTemporalLayerCount = tsLayers;
27994154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (tsLayers > 0) {
28004154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            for (size_t i = 0; i < OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS; i++) {
28014154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                vp8type.nTemporalLayerBitrateRatio[i] =
28024154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                    kVp8LayerRateAlloction[tsLayers - 1][i];
28034154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            }
28044154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
28054154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (bitrateMode == OMX_Video_ControlRateConstant) {
28064154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMinQuantizer = 2;
28074154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMaxQuantizer = 63;
28084154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
28094154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
28104154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        err = mOMX->setParameter(
28114154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
28124154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                &vp8type, sizeof(vp8type));
28134154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (err != OK) {
28144154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            ALOGW("Extended VP8 parameters set failed: %d", err);
28154154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
28164154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
28174154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
281889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    return configureBitrate(bitrate, bitrateMode);
281989b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber}
282089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
28215778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::verifySupportForProfileAndLevel(
28225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t profile, int32_t level) {
28235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
28245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&params);
28255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    params.nPortIndex = kPortIndexOutput;
28265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (params.nProfileIndex = 0;; ++params.nProfileIndex) {
28285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
28295778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode,
28305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                OMX_IndexParamVideoProfileLevelQuerySupported,
28315778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &params,
28325778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sizeof(params));
28335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
28355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
28365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
28375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
28395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
28405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (profile == supportedProfile && level <= supportedLevel) {
28425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OK;
28435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
28445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28455778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
28465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
284796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatus_t ACodec::configureBitrate(
284896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) {
28495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
28505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&bitrateType);
28515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
28525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
28545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
28555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
28565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
28585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
28595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
286196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    bitrateType.eControlRate = bitrateMode;
28625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nTargetBitrate = bitrate;
28635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
28655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
28665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
28675778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
28685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28695778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupErrorCorrectionParameters() {
28705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
28715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&errorCorrectionType);
28725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nPortIndex = kPortIndexOutput;
28735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
28755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
28765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
28775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
28795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OK;  // Optional feature. Ignore this failure
28805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableHEC = OMX_FALSE;
28835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableResync = OMX_TRUE;
28845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nResynchMarkerSpacing = 256;
28855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
28865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableRVLC = OMX_FALSE;
28875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
28895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
28905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
28915778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
28925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2893f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoFormatOnPort(
2894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
2895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat) {
2896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
2897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
2898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
2899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
2901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
2903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
2906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
2908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // XXX Need a (much) better heuristic to compute input buffer sizes.
2909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const size_t X = 64 * 1024;
2910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (def.nBufferSize < X) {
2911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.nBufferSize = X;
2912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
2916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameWidth = width;
2918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameHeight = height;
2919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
2921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eCompressionFormat = compressionFormat;
2922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eColorFormat = OMX_COLOR_FormatUnused;
2923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
2926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
2929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2931f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::initNativeWindow() {
2932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL) {
2933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
2934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
2937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2940d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Hubersize_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
2941d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    size_t n = 0;
2942d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2943d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2944d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        const BufferInfo &info = mBuffers[portIndex].itemAt(i);
2945d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2946d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
2947d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            ++n;
2948d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        }
2949d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    }
2950d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2951d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    return n;
2952d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber}
2953d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
29547e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubersize_t ACodec::countBuffersOwnedByNativeWindow() const {
29557e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    size_t n = 0;
29567e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
29577e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
29587e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
29597e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
29607e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
29617e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            ++n;
29627e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        }
29637e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
29647e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
29657e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    return n;
29667e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
29677e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
29687e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubervoid ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
29697e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (mNativeWindow == NULL) {
29707e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        return;
29717e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
29727e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
2973e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    while (countBuffersOwnedByNativeWindow() > mNumUndequeuedBuffers
29747e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            && dequeueBufferFromNativeWindow() != NULL) {
2975c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        // these buffers will be submitted as regular buffers; account for this
2976c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        if (mStoreMetaDataInOutputBuffers && mMetaDataBuffersToSubmit > 0) {
2977c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar            --mMetaDataBuffersToSubmit;
2978c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        }
29797e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
29807e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
29817e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
2982f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs(
2983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
2984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
2986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus != BufferInfo::OWNED_BY_US
2988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
2989609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGV("[%s] Buffer %u on port %u still has status %d",
2990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mComponentName.c_str(),
2991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info->mBufferID, portIndex, info->mStatus);
2992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
2993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2999f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs() {
3000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return allYourBuffersAreBelongToUs(kPortIndexInput)
3001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        && allYourBuffersAreBelongToUs(kPortIndexOutput);
3002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3004f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::deferMessage(const sp<AMessage> &msg) {
3005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool wasEmptyBefore = mDeferredQueue.empty();
3006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.push_back(msg);
3007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3009f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::processDeferredMessages() {
3010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> > queue = mDeferredQueue;
3011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.clear();
3012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> >::iterator it = queue.begin();
3014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while (it != queue.end()) {
3015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        onMessageReceived(*it++);
3016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
301903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar// static
3020229d242665c612fd97431d1e7ac004823b47f181Lajos Molnarbool ACodec::describeDefaultColorFormat(DescribeColorFormatParams &params) {
302103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    MediaImage &image = params.sMediaImage;
302203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    memset(&image, 0, sizeof(image));
302303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
302403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mType = MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
302503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mNumPlanes = 0;
302603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
302703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    const OMX_COLOR_FORMATTYPE fmt = params.eColorFormat;
302803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mWidth = params.nFrameWidth;
302903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mHeight = params.nFrameHeight;
303003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
303103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    // only supporting YUV420
303203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    if (fmt != OMX_COLOR_FormatYUV420Planar &&
303303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        fmt != OMX_COLOR_FormatYUV420PackedPlanar &&
303403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        fmt != OMX_COLOR_FormatYUV420SemiPlanar &&
303503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        fmt != OMX_COLOR_FormatYUV420PackedSemiPlanar) {
303603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        ALOGW("do not know color format 0x%x = %d", fmt, fmt);
3037229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return false;
303803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    }
303903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
3040b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    // TEMPORARY FIX for some vendors that advertise sliceHeight as 0
3041b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    if (params.nStride != 0 && params.nSliceHeight == 0) {
3042b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        ALOGW("using sliceHeight=%u instead of what codec advertised (=0)",
3043b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar                params.nFrameHeight);
3044b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        params.nSliceHeight = params.nFrameHeight;
3045b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    }
3046b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar
3047b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    // we need stride and slice-height to be non-zero
3048b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    if (params.nStride == 0 || params.nSliceHeight == 0) {
3049b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        ALOGW("cannot describe color format 0x%x = %d with stride=%u and sliceHeight=%u",
3050b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar                fmt, fmt, params.nStride, params.nSliceHeight);
3051b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        return false;
3052b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    }
3053b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar
305403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    // set-up YUV format
305503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mType = MediaImage::MEDIA_IMAGE_TYPE_YUV;
305603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mNumPlanes = 3;
305703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mBitDepth = 8;
305803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mOffset = 0;
305903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mColInc = 1;
306003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mRowInc = params.nStride;
306103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mHorizSubsampling = 1;
306203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mVertSubsampling = 1;
306303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
306403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    switch (fmt) {
306503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420Planar: // used for YV12
306603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420PackedPlanar:
306703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight;
306803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mColInc = 1;
306903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mRowInc = params.nStride / 2;
307003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mHorizSubsampling = 2;
307103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mVertSubsampling = 2;
307203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
307303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset
307403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    + (params.nStride * params.nSliceHeight / 4);
307503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mColInc = 1;
307603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mRowInc = params.nStride / 2;
307703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mHorizSubsampling = 2;
307803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mVertSubsampling = 2;
307903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            break;
308003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
308103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420SemiPlanar:
308203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            // FIXME: NV21 for sw-encoder, NV12 for decoder and hw-encoder
308303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420PackedSemiPlanar:
308403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            // NV12
308503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight;
308603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mColInc = 2;
308703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mRowInc = params.nStride;
308803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mHorizSubsampling = 2;
308903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mVertSubsampling = 2;
309003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
309103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset + 1;
309203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mColInc = 2;
309303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mRowInc = params.nStride;
309403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mHorizSubsampling = 2;
309503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mVertSubsampling = 2;
309603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            break;
309703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
309803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        default:
309903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            TRESPASS();
310003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    }
3101229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    return true;
3102229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar}
3103229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3104229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar// static
3105229d242665c612fd97431d1e7ac004823b47f181Lajos Molnarbool ACodec::describeColorFormat(
3106229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        const sp<IOMX> &omx, IOMX::node_id node,
3107229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        DescribeColorFormatParams &describeParams)
3108229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar{
3109229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    OMX_INDEXTYPE describeColorFormatIndex;
3110229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    if (omx->getExtensionIndex(
3111229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            node, "OMX.google.android.index.describeColorFormat",
3112229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            &describeColorFormatIndex) != OK ||
3113229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        omx->getParameter(
3114229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            node, describeColorFormatIndex,
3115229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            &describeParams, sizeof(describeParams)) != OK) {
3116229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return describeDefaultColorFormat(describeParams);
3117229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    }
3118229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    return describeParams.sMediaImage.mType !=
3119229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
3120229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar}
3121229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3122229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar// static
3123229d242665c612fd97431d1e7ac004823b47f181Lajos Molnarbool ACodec::isFlexibleColorFormat(
3124229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar         const sp<IOMX> &omx, IOMX::node_id node,
3125229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar         uint32_t colorFormat, OMX_U32 *flexibleEquivalent) {
3126229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    DescribeColorFormatParams describeParams;
3127229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    InitOMXParams(&describeParams);
3128229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.eColorFormat = (OMX_COLOR_FORMATTYPE)colorFormat;
3129229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    // reasonable dummy values
3130229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nFrameWidth = 128;
3131229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nFrameHeight = 128;
3132229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nStride = 128;
3133229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nSliceHeight = 128;
3134229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3135229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    CHECK(flexibleEquivalent != NULL);
3136229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3137229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    if (!describeColorFormat(omx, node, describeParams)) {
3138229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return false;
3139229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    }
3140229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3141229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    const MediaImage &img = describeParams.sMediaImage;
3142229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    if (img.mType == MediaImage::MEDIA_IMAGE_TYPE_YUV) {
3143229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        if (img.mNumPlanes != 3 ||
3144229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            img.mPlane[img.Y].mHorizSubsampling != 1 ||
3145229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            img.mPlane[img.Y].mVertSubsampling != 1) {
3146229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            return false;
3147229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
3148229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3149229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        // YUV 420
3150229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        if (img.mPlane[img.U].mHorizSubsampling == 2
3151229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.U].mVertSubsampling == 2
3152229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.V].mHorizSubsampling == 2
3153229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.V].mVertSubsampling == 2) {
3154229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            // possible flexible YUV420 format
3155229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            if (img.mBitDepth <= 8) {
3156229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar               *flexibleEquivalent = OMX_COLOR_FormatYUV420Flexible;
3157229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar               return true;
3158229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            }
3159229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
3160229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    }
3161229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    return false;
316203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar}
316303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
3164e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarstatus_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> &notify) {
3165e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    // TODO: catch errors an return them instead of using CHECK
316631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
316731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    InitOMXParams(&def);
3168e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    def.nPortIndex = portIndex;
316931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
317031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ(mOMX->getParameter(
317131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)),
317231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber             (status_t)OK);
317331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3174e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ((int)def.eDir,
3175e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            (int)(portIndex == kPortIndexOutput ? OMX_DirOutput : OMX_DirInput));
317631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
317731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    switch (def.eDomain) {
317831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainVideo:
317931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
318031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
3181e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            switch ((int)videoDef->eCompressionFormat) {
3182e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_VIDEO_CodingUnused:
3183e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3184e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(mIsEncoder ^ (portIndex == kPortIndexOutput));
3185e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
3186e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3187e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("stride", videoDef->nStride);
3188e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("slice-height", videoDef->nSliceHeight);
3189e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("color-format", videoDef->eColorFormat);
3190e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
319103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    DescribeColorFormatParams describeParams;
319203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    InitOMXParams(&describeParams);
319303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    describeParams.eColorFormat = videoDef->eColorFormat;
319403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    describeParams.nFrameWidth = videoDef->nFrameWidth;
319503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    describeParams.nFrameHeight = videoDef->nFrameHeight;
319603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    describeParams.nStride = videoDef->nStride;
319703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    describeParams.nSliceHeight = videoDef->nSliceHeight;
319803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
3199229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                    if (describeColorFormat(mOMX, mNode, describeParams)) {
320003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                        notify->setBuffer(
320103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                                "image-data",
320203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                                ABuffer::CreateAsCopy(
320303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                                        &describeParams.sMediaImage,
320403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                                        sizeof(describeParams.sMediaImage)));
320503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    }
320603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
320791a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                    if (portIndex != kPortIndexOutput) {
320891a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                        // TODO: also get input crop
320991a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                        break;
321091a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                    }
321191a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar
3212e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_CONFIG_RECTTYPE rect;
3213e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&rect);
321491a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                    rect.nPortIndex = portIndex;
3215e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3216e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    if (mOMX->getConfig(
321791a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                mNode,
321891a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                (portIndex == kPortIndexOutput ?
321991a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                        OMX_IndexConfigCommonOutputCrop :
322091a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                        OMX_IndexConfigCommonInputCrop),
3221e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &rect, sizeof(rect)) != OK) {
3222e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nLeft = 0;
3223e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nTop = 0;
3224e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nWidth = videoDef->nFrameWidth;
3225e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nHeight = videoDef->nFrameHeight;
3226e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    }
322731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3228e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nLeft, 0);
3229e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nTop, 0);
3230e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nWidth, 0u);
3231e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nHeight, 0u);
3232e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_LE(rect.nLeft + rect.nWidth - 1, videoDef->nFrameWidth);
3233e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_LE(rect.nTop + rect.nHeight - 1, videoDef->nFrameHeight);
3234e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3235e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setRect(
3236577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            "crop",
3237577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nLeft,
3238577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nTop,
3239e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                            rect.nLeft + rect.nWidth - 1,
3240e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                            rect.nTop + rect.nHeight - 1);
3241e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3242e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3243e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
32444730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
32454730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP8:
32464730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP9:
32474730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                {
32484730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
32494730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    InitOMXParams(&vp8type);
32504730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    vp8type.nPortIndex = kPortIndexOutput;
32514730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    status_t err = mOMX->getParameter(
32524730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            mNode,
32534730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
32544730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            &vp8type,
32554730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            sizeof(vp8type));
32564730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
32574730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    if (err == OK) {
32584730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        AString tsSchema = "none";
32594730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        if (vp8type.eTemporalPattern
32604730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                == OMX_VIDEO_VPXTemporalLayerPatternWebRTC) {
32614730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            switch (vp8type.nTemporalLayerCount) {
32624730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 1:
32634730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
32644730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.1-layer";
32654730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
32664730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
32674730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 2:
32684730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
32694730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.2-layer";
32704730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
32714730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
32724730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 3:
32734730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
32744730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.3-layer";
32754730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
32764730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
32774730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                default:
32784730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
32794730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
32804730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
32814730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            }
32824730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        }
32834730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        notify->setString("ts-schema", tsSchema);
32844730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    }
32854730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    // Fall through to set up mime.
32864730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                }
32874730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
3288e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                default:
3289e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3290e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(mIsEncoder ^ (portIndex == kPortIndexInput));
3291e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    AString mime;
3292e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    if (GetMimeTypeForVideoCoding(
3293e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        videoDef->eCompressionFormat, &mime) != OK) {
3294e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", "application/octet-stream");
3295e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    } else {
3296e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", mime.c_str());
3297e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    }
3298e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3299e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
330031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            }
3301e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3302e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("width", videoDef->nFrameWidth);
3303e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("height", videoDef->nFrameHeight);
330431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
330531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
330631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
330731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainAudio:
330831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
330931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
331031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
331197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            switch ((int)audioDef->eEncoding) {
3312e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingPCM:
3313e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3314e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_PCMMODETYPE params;
3315e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3316e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3317e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3318e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3319e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioPcm,
3320e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3321e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3322e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
332314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_GT(params.nChannels, 0);
3324e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK(params.nChannels == 1 || params.bInterleaved);
3325e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(params.nBitPerSample, 16u);
332614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
332714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.eNumData,
332814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_NumericalDataSigned);
332914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
333014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.ePCMMode,
333114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_AUDIO_PCMModeLinear);
3332e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3333e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
3334e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
3335e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSamplingRate);
3336e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3337e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mChannelMaskPresent) {
3338e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("channel-mask", mChannelMask);
33398b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                    }
3340e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
33418b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                }
33429806555d3930be43e11106281dee354820ac1c88Andreas Huber
3343e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAAC:
3344e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3345e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AACPROFILETYPE params;
3346e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3347e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3348e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3349e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3350e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAac,
3351e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3352e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3353e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3354e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
3355e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
3356e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
3357e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
3358e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
3359e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3360e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAMR:
3361e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3362e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AMRTYPE params;
3363e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3364e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
33659806555d3930be43e11106281dee354820ac1c88Andreas Huber
3366e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3367e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAmr,
3368e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3369e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3370e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3371e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", 1);
3372e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) {
3373e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
3374e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_WB);
3375e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3376e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 16000);
3377e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    } else {
3378e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
3379e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
3380e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3381e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 8000);
3382e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
3383e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
3384e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
3385e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3386e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingFLAC:
3387e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3388e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_FLACTYPE params;
3389e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3390e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3391e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3392e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3393e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioFlac,
3394e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3395e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3396e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3397e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC);
3398e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
3399e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
3400e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
3401e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
3402e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3403e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingMP3:
3404e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3405e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_MP3TYPE params;
3406e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
3407e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3408e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3409e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_EQ(mOMX->getParameter(
3410e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                mNode, OMX_IndexParamAudioMp3,
3411e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &params, sizeof(params)),
3412e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                             (status_t)OK);
3413e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3414e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MPEG);
3415e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
3416e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
3417e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3418e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
3419e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3420e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingVORBIS:
3421e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3422e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_VORBISTYPE params;
3423e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
3424e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3425e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3426e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_EQ(mOMX->getParameter(
3427e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                mNode, OMX_IndexParamAudioVorbis,
3428e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &params, sizeof(params)),
3429e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                             (status_t)OK);
3430e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3431e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_VORBIS);
3432e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
3433e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
3434e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3435e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
3436e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
343797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                case OMX_AUDIO_CodingAndroidAC3:
343897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                {
343997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    OMX_AUDIO_PARAM_ANDROID_AC3TYPE params;
344097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    InitOMXParams(&params);
3441e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
344297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
344397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    CHECK_EQ((status_t)OK, mOMX->getParameter(
344497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            mNode,
344597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
344697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            &params,
344797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            sizeof(params)));
344897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
344997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AC3);
345097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("channel-count", params.nChannels);
345197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("sample-rate", params.nSampleRate);
345297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    break;
345397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                }
3454e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
34558c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                case OMX_AUDIO_CodingAndroidOPUS:
34568c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                {
34578c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    OMX_AUDIO_PARAM_ANDROID_OPUSTYPE params;
34588c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    InitOMXParams(&params);
34598c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    params.nPortIndex = portIndex;
34608c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
34618c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    CHECK_EQ((status_t)OK, mOMX->getParameter(
34628c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            mNode,
34638c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus,
34648c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            &params,
34658c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            sizeof(params)));
34668c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
34678c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_OPUS);
34688c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("channel-count", params.nChannels);
34698c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("sample-rate", params.nSampleRate);
34708c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    break;
34718c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                }
34728c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
347310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                case OMX_AUDIO_CodingG711:
347410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                {
347510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    OMX_AUDIO_PARAM_PCMMODETYPE params;
347610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    InitOMXParams(&params);
347710d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    params.nPortIndex = portIndex;
347810d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
347910d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    CHECK_EQ((status_t)OK, mOMX->getParameter(
348010d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                            mNode,
348110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                            (OMX_INDEXTYPE)OMX_IndexParamAudioPcm,
348210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                            &params,
348310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                            sizeof(params)));
348410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
348510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    const char *mime = NULL;
348610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    if (params.ePCMMode == OMX_AUDIO_PCMModeMULaw) {
348710d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_G711_MLAW;
348810d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    } else if (params.ePCMMode == OMX_AUDIO_PCMModeALaw) {
348910d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_G711_ALAW;
349010d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    } else { // params.ePCMMode == OMX_AUDIO_PCMModeLinear
349110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_RAW;
349210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    }
349310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setString("mime", mime);
349410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setInt32("channel-count", params.nChannels);
349510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setInt32("sample-rate", params.nSamplingRate);
349610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    break;
349710d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                }
349810d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
3499e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                default:
3500e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    ALOGE("UNKNOWN AUDIO CODING: %d\n", audioDef->eEncoding);
3501e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    TRESPASS();
3502e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
350331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
350431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
350531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
350631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        default:
350731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            TRESPASS();
350831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    }
350931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3510e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    return OK;
3511e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar}
3512e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3513e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarvoid ACodec::sendFormatChange(const sp<AMessage> &reply) {
3514e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    sp<AMessage> notify = mNotify->dup();
3515e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    notify->setInt32("what", kWhatOutputFormatChanged);
3516e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3517e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ(getPortFormat(kPortIndexOutput, notify), (status_t)OK);
3518e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3519e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    AString mime;
3520e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK(notify->findString("mime", &mime));
3521e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3522e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    int32_t left, top, right, bottom;
3523e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if (mime == MEDIA_MIMETYPE_VIDEO_RAW &&
3524e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        mNativeWindow != NULL &&
3525e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->findRect("crop", &left, &top, &right, &bottom)) {
3526e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        // notify renderer of the crop change
3527e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        // NOTE: native window uses extended right-bottom coordinate
3528e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        reply->setRect("crop", left, top, right + 1, bottom + 1);
3529e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    } else if (mime == MEDIA_MIMETYPE_AUDIO_RAW &&
3530e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar               (mEncoderDelay || mEncoderPadding)) {
3531e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        int32_t channelCount;
3532e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        CHECK(notify->findInt32("channel-count", &channelCount));
3533e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        size_t frameSize = channelCount * sizeof(int16_t);
3534e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        if (mSkipCutBuffer != NULL) {
3535e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            size_t prevbufsize = mSkipCutBuffer->size();
3536e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            if (prevbufsize != 0) {
3537e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                ALOGW("Replacing SkipCutBuffer holding %d "
3538e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                      "bytes",
3539e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                      prevbufsize);
3540e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            }
3541e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        }
3542e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        mSkipCutBuffer = new SkipCutBuffer(
3543e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                mEncoderDelay * frameSize,
3544e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                mEncoderPadding * frameSize);
3545e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
3546e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
354731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->post();
354831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
354931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mSentFormat = true;
355031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber}
355131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
35525778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
3553cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    sp<AMessage> notify = mNotify->dup();
3554d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatError);
3555251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    ALOGE("signalError(omxError %#x, internalError %d)", error, internalError);
3556251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
3557251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (internalError == UNKNOWN_ERROR) { // find better error code
3558251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        const status_t omxStatus = statusFromOMXError(error);
3559251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        if (omxStatus != 0) {
3560251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            internalError = omxStatus;
3561251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        } else {
3562251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            ALOGW("Invalid OMX error %#x", error);
3563251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        }
3564251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
35655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("err", internalError);
3566251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    notify->setInt32("actionCode", ACTION_CODE_FATAL); // could translate from OMX error.
3567cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->post();
3568cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber}
3569cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber
3570bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huberstatus_t ACodec::pushBlankBuffersToNativeWindow() {
3571bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    status_t err = NO_ERROR;
3572bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    ANativeWindowBuffer* anb = NULL;
3573bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int numBufs = 0;
3574bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int minUndequeuedBufs = 0;
3575bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3576bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We need to reconnect to the ANativeWindow as a CPU client to ensure that
3577bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // no frames get dropped by SurfaceFlinger assuming that these are video
3578bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // frames.
3579bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_disconnect(mNativeWindow.get(),
3580bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_MEDIA);
3581bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3582bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
3583bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3584bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
3585bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3586bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3587bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_connect(mNativeWindow.get(),
3588bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_CPU);
3589bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3590bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
3591bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3592bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
3593bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3594bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3595bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffers_geometry(mNativeWindow.get(), 1, 1,
3596bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            HAL_PIXEL_FORMAT_RGBX_8888);
3597bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3598bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffers_geometry failed: %s (%d)",
3599bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3600bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
3601bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3602bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
360387eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin    err = native_window_set_scaling_mode(mNativeWindow.get(),
360487eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
360587eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin    if (err != NO_ERROR) {
360687eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin        ALOGE("error pushing blank_frames: set_scaling_mode failed: %s (%d)",
360787eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin              strerror(-err), -err);
360887eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin        goto error;
3609bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3610bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3611bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_usage(mNativeWindow.get(),
3612bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            GRALLOC_USAGE_SW_WRITE_OFTEN);
3613bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3614bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_usage failed: %s (%d)",
3615bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3616bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
3617bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3618bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3619bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = mNativeWindow->query(mNativeWindow.get(),
3620bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs);
3621bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3622bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: MIN_UNDEQUEUED_BUFFERS query "
3623bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                "failed: %s (%d)", strerror(-err), -err);
3624bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
3625bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3626bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3627bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    numBufs = minUndequeuedBufs + 1;
3628bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffer_count(mNativeWindow.get(), numBufs);
3629bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3630bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffer_count failed: %s (%d)",
3631bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3632bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
3633bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3634bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3635bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We  push numBufs + 1 buffers to ensure that we've drawn into the same
3636bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // buffer twice.  This should guarantee that the buffer has been displayed
3637bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // on the screen and then been replaced, so an previous video frames are
3638bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // guaranteed NOT to be currently displayed.
3639bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    for (int i = 0; i < numBufs + 1; i++) {
36401e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        int fenceFd = -1;
36411e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &anb);
3642bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3643bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: dequeueBuffer failed: %s (%d)",
3644bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3645bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
3646bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3647bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3648bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
3649bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3650bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Fill the buffer with the a 1x1 checkerboard pattern ;)
3651bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        uint32_t* img = NULL;
3652bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
3653bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3654bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: lock failed: %s (%d)",
3655bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3656bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
3657bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3658bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3659bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        *img = 0;
3660bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3661bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->unlock();
3662bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3663bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: unlock failed: %s (%d)",
3664bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3665bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
3666bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3667bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3668bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->queueBuffer(mNativeWindow.get(),
36691e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                buf->getNativeBuffer(), -1);
3670bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3671bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: queueBuffer failed: %s (%d)",
3672bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3673bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
3674bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3675bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3676bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        anb = NULL;
3677bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3678bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3679bc098410be55f9d96f394b3981a0c482b83859b6Andreas Hubererror:
3680bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3681bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3682bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after an error.
3683bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (anb != NULL) {
36841e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis            mNativeWindow->cancelBuffer(mNativeWindow.get(), anb, -1);
3685bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3686bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3687bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_disconnect(mNativeWindow.get(),
3688bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
3689bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_connect(mNativeWindow.get(),
3690bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
3691bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3692bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
3693bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    } else {
3694bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after success.
3695bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_disconnect(mNativeWindow.get(),
3696bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
3697bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3698bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
3699bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3700bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
3701bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3702bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3703bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_connect(mNativeWindow.get(),
3704bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
3705bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3706bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
3707bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3708bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
3709bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3710bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3711bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return NO_ERROR;
3712bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3713bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber}
3714bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3717eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberACodec::PortDescription::PortDescription() {
3718eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3719eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3720496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t ACodec::requestIDRFrame() {
3721496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    if (!mIsEncoder) {
3722496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        return ERROR_UNSUPPORTED;
3723496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    }
3724496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
3725496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    OMX_CONFIG_INTRAREFRESHVOPTYPE params;
3726496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    InitOMXParams(&params);
3727496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
3728496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.nPortIndex = kPortIndexOutput;
3729496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.IntraRefreshVOP = OMX_TRUE;
3730496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
3731496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    return mOMX->setConfig(
3732496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            mNode,
3733496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            OMX_IndexConfigVideoIntraVOPRefresh,
3734496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            &params,
3735496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            sizeof(params));
3736496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
3737496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
3738eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubervoid ACodec::PortDescription::addBuffer(
3739eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        IOMX::buffer_id id, const sp<ABuffer> &buffer) {
3740eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBufferIDs.push_back(id);
3741eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBuffers.push_back(buffer);
3742eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3743eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3744eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersize_t ACodec::PortDescription::countBuffers() {
3745eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.size();
3746eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3747eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3748eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberIOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const {
3749eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.itemAt(index);
3750eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3751eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3752eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const {
3753eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBuffers.itemAt(index);
3754eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3755eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3756eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber////////////////////////////////////////////////////////////////////////////////
3757eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3758f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
3759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : AState(parentState),
3760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mCodec(codec) {
3761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3763ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas HuberACodec::BaseState::PortMode ACodec::BaseState::getPortMode(
3764ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
3765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return KEEP_BUFFERS;
3766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3768f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
3769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatInputBufferFilled:
3771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onInputBufferFilled(msg);
3773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3775f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatOutputBufferDrained:
3777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onOutputBufferDrained(msg);
3779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatOMXMessage:
3783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXMessage(msg);
3785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
37877cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
37887cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
37897cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
3790251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            // This may result in an app illegal state exception.
37917cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            ALOGE("Message 0x%x was not handled", msg->what());
37927cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
37937cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            return true;
37947cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
37957cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
3796ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        case ACodec::kWhatOMXDied:
3797ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        {
3798251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            // This will result in kFlagSawMediaServerDie handling in MediaCodec.
3799ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            ALOGE("OMX/mediaserver died, signalling error!");
3800ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT);
3801ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            break;
3802ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        }
3803ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
380430358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        case ACodec::kWhatReleaseCodecInstance:
380530358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        {
380630358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            ALOGI("[%s] forcing the release of codec",
380730358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar                    mCodec->mComponentName.c_str());
380830358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            status_t err = mCodec->mOMX->freeNode(mCodec->mNode);
380930358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            ALOGE_IF("[%s] failed to release codec instance: err=%d",
381030358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar                       mCodec->mComponentName.c_str(), err);
381130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            sp<AMessage> notify = mCodec->mNotify->dup();
381230358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
381330358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            notify->post();
381430358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            break;
381530358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        }
381630358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar
3817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
3819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3824f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
3825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t type;
3826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findInt32("type", &type));
3827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
38285e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // there is a possibility that this is an outstanding message for a
38295e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // codec that we have already destroyed
38305e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    if (mCodec->mNode == NULL) {
38315e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar        ALOGI("ignoring message as already freed component: %s",
38325e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar                msg->debugString().c_str());
38335e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar        return true;
38345e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    }
38355e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar
3836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::node_id nodeID;
3837609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("node", (int32_t*)&nodeID));
3838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(nodeID, mCodec->mNode);
3839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3840f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (type) {
3841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EVENT:
3842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t event, data1, data2;
3844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("event", &event));
3845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data1", &data1));
3846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data2", &data2));
3847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
38480af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            if (event == OMX_EventCmdComplete
38490af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data1 == OMX_CommandFlush
38500af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data2 == (int32_t)OMX_ALL) {
38510af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // Use of this notification is not consistent across
38520af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // implementations. We'll drop this notification and rely
38530af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // on flush-complete notifications on the individual port
38540af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // indices instead.
38550af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
38560af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                return true;
38570af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            }
38580af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
3859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEvent(
3860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_EVENTTYPE>(event),
3861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data1),
3862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data2));
3863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EMPTY_BUFFER_DONE:
3866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
3868609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
3869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEmptyBufferDone(bufferID);
3871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::FILL_BUFFER_DONE:
3874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
3876609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
3877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t rangeOffset, rangeLength, flags;
3879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs;
3880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_offset", &rangeOffset));
3882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_length", &rangeLength));
3883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("flags", &flags));
3884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt64("timestamp", &timeUs));
3885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXFillBufferDone(
3887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    bufferID,
3888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (size_t)rangeOffset, (size_t)rangeLength,
3889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (OMX_U32)flags,
3890784e24e386b088c05d653ab482f2e95cb53e3d01Andy Hung                    timeUs);
3891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
3895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3899f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEvent(
3900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (event != OMX_EventError) {
39023856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] EVENT(%d, 0x%08lx, 0x%08lx)",
3903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mCodec->mComponentName.c_str(), event, data1, data2);
3904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return false;
3906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
390829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block    ALOGE("[%s] ERROR(0x%08lx)", mCodec->mComponentName.c_str(), data1);
3909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3910251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // verify OMX component sends back an error we expect.
3911251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    OMX_ERRORTYPE omxError = (OMX_ERRORTYPE)data1;
3912251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (!isOMXError(omxError)) {
3913251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        ALOGW("Invalid OMX error %#x", omxError);
3914251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        omxError = OMX_ErrorUndefined;
3915251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
3916251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    mCodec->signalError(omxError);
3917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3921f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID) {
39223856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] onOMXEmptyBufferDone %p",
3923349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber         mCodec->mComponentName.c_str(), bufferID);
3924349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexInput, bufferID);
3927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
3929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
393196e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // We're in "store-metadata-in-buffers" mode, the underlying
393296e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // OMX component had access to data that's implicitly refcounted
393396e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // by this "MediaBuffer" object. Now that the OMX component has
393496e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // told us that it's done with the input buffer, we can decrement
393596e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // the mediaBuffer's reference count.
393696e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    info->mData->setMediaBufferBase(NULL);
3937d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
3939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            postFillThisBuffer(info);
3946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();  // Not currently used
3952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3959f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
3960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
3961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
3965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
3967d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatFillThisBuffer);
3968609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    notify->setInt32("buffer-id", info->mBufferID);
3969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mData->meta()->clear();
39712d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    notify->setBuffer("buffer", info->mData);
3972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec->id());
3974609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    reply->setInt32("buffer-id", info->mBufferID);
3975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setMessage("reply", reply);
3977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->post();
3979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
3981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3983f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
3984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
3985609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
39862d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    sp<ABuffer> buffer;
3987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t err = OK;
39885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool eos = false;
3989a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar    PortMode mode = getPortMode(kPortIndexInput);
39905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39912d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    if (!msg->findBuffer("buffer", &buffer)) {
3992a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar        /* these are unfilled buffers returned by client */
3993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findInt32("err", &err));
3994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
39957fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        if (err == OK) {
39967fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            /* buffers with no errors are returned on MediaCodec.flush */
39977fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            mode = KEEP_BUFFERS;
39987fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        } else {
39997fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            ALOGV("[%s] saw error %d instead of an input buffer",
40007fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                 mCodec->mComponentName.c_str(), err);
40017fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            eos = true;
40027fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        }
40033831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
40042d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber        buffer.clear();
4005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
40075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
40085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
40095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
40105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = ERROR_END_OF_STREAM;
40115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
40125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
4014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_UPSTREAM);
4015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
4017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
40215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (eos) {
4022dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (!mCodec->mPortEOS[kPortIndexInput]) {
4023dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
4024dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mInputEOSResult = err;
4025dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
4026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
40325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
4033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int64_t timeUs;
4034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
4035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
4037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t isCSD;
4039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
4040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
4041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
4042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
40435778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (eos) {
40445778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    flags |= OMX_BUFFERFLAG_EOS;
40455778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
40465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer != info->mData) {
4048d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGV("[%s] Needs to copy input data for buffer %p. (%p != %p)",
4049d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(),
4050d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         bufferID,
4051d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         buffer.get(), info->mData.get());
4052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    CHECK_LE(buffer->size(), info->mData->capacity());
4054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    memcpy(info->mData->data(), buffer->data(), buffer->size());
4055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
4056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4057078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
40583856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ codec specific data",
4059078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID);
40605778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else if (flags & OMX_BUFFERFLAG_EOS) {
40615778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] calling emptyBuffer %p w/ EOS",
40625778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str(), bufferID);
4063078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                } else {
4064d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
4065d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGI("[%s] calling emptyBuffer %p w/ time %lld us",
4066d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
4067d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#else
40683856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ time %lld us",
4069078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
4070d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
4071078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                }
4072349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4073d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
4074d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ACodec::BufferStats stats;
4075d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
4076d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mFillBufferDoneTimeUs = -1ll;
4077d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mCodec->mBufferStats.add(timeUs, stats);
4078d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
4079d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4080054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                if (mCodec->mStoreMetaDataInOutputBuffers) {
4081054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    // try to submit an output buffer for each input buffer
4082054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    PortMode outputMode = getPortMode(kPortIndexOutput);
4083054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4084054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    ALOGV("MetaDataBuffersToSubmit=%u portMode=%s",
4085054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            mCodec->mMetaDataBuffersToSubmit,
4086054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            (outputMode == FREE_BUFFERS ? "FREE" :
4087054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                             outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
4088054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    if (outputMode == RESUBMIT_BUFFERS) {
4089e53350373ac516257b4f8956ff1e3f1ac48f607eLajos Molnar                        mCodec->submitOutputMetaDataBuffer();
4090054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    }
4091054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                }
4092054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
4094f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
4095f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
4096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
4097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            buffer->size(),
4098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            flags,
4099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            timeUs),
4100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
41045778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (!eos) {
41055778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    getMoreInputDataIfPossible();
41065778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
41075778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] Signalled EOS on the input port",
41085778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str());
41095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41105778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
41115778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mInputEOSResult = err;
41125778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
4113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
4114dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (err != ERROR_END_OF_STREAM) {
41153856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port "
4116dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         "due to error %d",
4117dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str(), err);
4118dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                } else {
41193856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port",
4120dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str());
4121dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
4122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
41233856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] calling emptyBuffer %p signalling EOS",
4124349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                     mCodec->mComponentName.c_str(), bufferID);
4125349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
4127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
4128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
4129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
4130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
4131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_BUFFERFLAG_EOS,
4132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0),
4133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexInput] = true;
4138dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                mCodec->mInputEOSResult = err;
4139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4142625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih
4143625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih        default:
4144625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
4145625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih            break;
4146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4149f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::getMoreInputDataIfPossible() {
4150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
4151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
4152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *eligible = NULL;
4155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
4157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
4158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
4160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
4161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // There's already a "read" pending.
4162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
4163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
4165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_US) {
4167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            eligible = info;
4168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (eligible == NULL) {
4172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
4173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(eligible);
4176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4178f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXFillBufferDone(
4179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferID,
4180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        size_t rangeOffset, size_t rangeLength,
4181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 flags,
4182784e24e386b088c05d653ab482f2e95cb53e3d01Andy Hung        int64_t timeUs) {
4183609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] onOMXFillBufferDone %u time %" PRId64 " us, flags = 0x%08x",
41845778822d86b0337407514b9372562b86edfa91cdAndreas Huber         mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
4185349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
4187d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4188d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
4189d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    index = mCodec->mBufferStats.indexOfKey(timeUs);
4190d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (index >= 0) {
4191d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
4192d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
4193d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4194d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ALOGI("frame PTS %lld: %lld",
4195d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                timeUs,
4196d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
4197d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4198d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mCodec->mBufferStats.removeItemsAt(index);
4199d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats = NULL;
4200d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
4201d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
4202d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
4204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
4205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
4207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4208054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mDequeuedAt = ++mCodec->mDequeueCounter;
4209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
4210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
4212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
42195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (rangeLength == 0 && !(flags & OMX_BUFFERFLAG_EOS)) {
4220609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                ALOGV("[%s] calling fillBuffer %u",
42215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                     mCodec->mComponentName.c_str(), info->mBufferID);
4222349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
42235778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK_EQ(mCodec->mOMX->fillBuffer(
42245778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mCodec->mNode, info->mBufferID),
42255778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         (status_t)OK);
4226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
42275778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
42285778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
42295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
423031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4231577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            sp<AMessage> reply =
4232577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                new AMessage(kWhatOutputBufferDrained, mCodec->id());
4233577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
42344bdda35319d5f46efea2089b865c8a64816389cdMarco Nelissen            if (!mCodec->mSentFormat && rangeLength > 0) {
4235577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->sendFormatChange(reply);
42365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
4237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4238308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            if (mCodec->mUseMetadataOnEncoderOutput) {
4239308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                native_handle_t* handle =
4240308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        *(native_handle_t**)(info->mData->data() + 4);
4241308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setPointer("handle", handle);
4242308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeOffset", rangeOffset);
4243308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeLength", rangeLength);
4244308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            } else {
4245308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->setRange(rangeOffset, rangeLength);
4246308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            }
4247496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#if 0
424821ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen            if (mCodec->mNativeWindow == NULL) {
4249496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                if (IsIDR(info->mData)) {
4250496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                    ALOGI("IDR frame");
4251496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                }
42525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
425321ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen#endif
4254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
42558b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            if (mCodec->mSkipCutBuffer != NULL) {
42568b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                mCodec->mSkipCutBuffer->submit(info->mData);
42578b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            }
42585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mData->meta()->setInt64("timeUs", timeUs);
4259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
42605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4261d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatDrainThisBuffer);
4262609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            notify->setInt32("buffer-id", info->mBufferID);
42632d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            notify->setBuffer("buffer", info->mData);
42645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("flags", flags);
4265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4266609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            reply->setInt32("buffer-id", info->mBufferID);
4267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
42685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setMessage("reply", reply);
4269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
42705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->post();
42715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
42725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
4273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (flags & OMX_BUFFERFLAG_EOS) {
42755778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
42765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                sp<AMessage> notify = mCodec->mNotify->dup();
4278d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar                notify->setInt32("what", CodecBase::kWhatEOS);
4279dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                notify->setInt32("err", mCodec->mInputEOSResult);
4280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->post();
4281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexOutput] = true;
4283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
4290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
4292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
4293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4300f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
4301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
4302609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
4303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
4304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
4305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
4306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM);
4307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4308577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    android_native_rect_t crop;
4309577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    if (msg->findRect("crop",
4310577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            &crop.left, &crop.top, &crop.right, &crop.bottom)) {
4311577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar        CHECK_EQ(0, native_window_set_crop(
4312577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->mNativeWindow.get(), &crop));
4313577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    }
4314577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
4315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t render;
4316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mNativeWindow != NULL
43176aade6058521b0dbd35a9a4620f4d04f02f90444Marco Nelissen            && msg->findInt32("render", &render) && render != 0
431879ee2399b67c7a11042c5904dc1309712a76f8cbJianzheng Zhou            && info->mData != NULL && info->mData->size() != 0) {
43196fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        ATRACE_NAME("render");
4320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The client wants this buffer to be rendered.
4321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4322fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        int64_t timestampNs = 0;
4323fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        if (!msg->findInt64("timestampNs", &timestampNs)) {
4324fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // TODO: it seems like we should use the timestamp
4325fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // in the (media)buffer as it potentially came from
4326fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // an input surface, but we did not propagate it prior to
4327fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // API 20.  Perhaps check for target SDK version.
4328fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#if 0
4329fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            if (info->mData->meta()->findInt64("timeUs", &timestampNs)) {
433047aea1f7c58f5302b16822f9e7e1763f2af04ef5Lajos Molnar                ALOGV("using buffer PTS of %" PRId64, timestampNs);
4331fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar                timestampNs *= 1000;
4332fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            }
4333fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#endif
4334fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
4335fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
43365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err;
4337fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        err = native_window_set_buffers_timestamp(mCodec->mNativeWindow.get(), timestampNs);
4338fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        if (err != OK) {
4339fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            ALOGW("failed to set buffer timestamp: %d", err);
4340fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
4341fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
43425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if ((err = mCodec->mNativeWindow->queueBuffer(
4343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNativeWindow.get(),
43441e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                    info->mGraphicBuffer.get(), -1)) == OK) {
4345cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
4346cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        } else {
4347251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
4348cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
4349cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        }
4350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
43516fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        if (mCodec->mNativeWindow != NULL &&
43526fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar            (info->mData == NULL || info->mData->size() != 0)) {
43536fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar            ATRACE_NAME("frame-drop");
43546fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        }
4355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_US;
4356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
4359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
4364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // We cannot resubmit the buffer we just rendered, dequeue
4367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // the spare instead.
4368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info = mCodec->dequeueBufferFromNativeWindow();
4370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (!mCodec->mPortEOS[kPortIndexOutput]) {
4377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // We cannot resubmit the buffer we just rendered, dequeue
4379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // the spare instead.
4380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info = mCodec->dequeueBufferFromNativeWindow();
4382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
4383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4384c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                if (info != NULL) {
4385609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                    ALOGV("[%s] calling fillBuffer %u",
4386c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                         mCodec->mComponentName.c_str(), info->mBufferID);
4387349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4388c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
4389c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                             (status_t)OK);
4390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4391c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4392c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                }
4393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
4400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
4402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
4403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4410f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::UninitializedState::UninitializedState(ACodec *codec)
4411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4414c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::UninitializedState::stateEntered() {
4415c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("Now uninitialized");
4416ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4417ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (mDeathNotifier != NULL) {
4418ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mCodec->mOMX->asBinder()->unlinkToDeath(mDeathNotifier);
4419ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
4420ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
4421ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4422ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNativeWindow.clear();
4423ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNode = NULL;
4424ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mOMX.clear();
4425ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mQuirks = 0;
4426ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mFlags = 0;
4427308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    mCodec->mUseMetadataOnEncoderOutput = 0;
4428ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mComponentName.clear();
4429c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4430c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4431f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
4432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatSetup:
4436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onSetup(msg);
4438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
44435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case ACodec::kWhatAllocateComponent:
44445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
44455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            onAllocateComponent(msg);
44465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            handled = true;
44475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
44485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
44495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatShutdown:
4451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4452c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
4453c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
4454c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
445554b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            ALOGW_IF(keepComponentAllocated,
445654b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar                     "cannot keep component allocated on shutdown in Uninitialized state");
4457c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4459d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
4460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
4461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4463c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
4464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatFlush:
4467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4469d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
4470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
4471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4473c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
4474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
447630358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        case ACodec::kWhatReleaseCodecInstance:
447730358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        {
447830358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            // nothing to do, as we have already signaled shutdown
447930358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            handled = true;
448030358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            break;
448130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        }
448230358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar
4483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
4485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4490f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::UninitializedState::onSetup(
4491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4492c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (onAllocateComponent(msg)
4493c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            && mCodec->mLoadedState->onConfigureComponent(msg)) {
4494c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mLoadedState->onStart();
4495c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
44965778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
44975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4498c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
44995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onAllocateComponent");
45005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4501c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    CHECK(mCodec->mNode == NULL);
45025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMXClient client;
4504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(client.connect(), (status_t)OK);
4505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<IOMX> omx = client.interface();
4507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4508ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec->id());
4509ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4510ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mDeathNotifier = new DeathNotifier(notify);
4511ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (omx->asBinder()->linkToDeath(mDeathNotifier) != OK) {
4512ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // This was a local binder, if it dies so do we, we won't care
4513ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // about any notifications in the afterlife.
4514ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
4515ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
4516ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4517e671207115fac3914134c61b336d5fa0242c68caAndreas Huber    Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs;
45185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    AString mime;
4520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
45215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString componentName;
4522d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint32_t quirks = 0;
45237791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen    int32_t encoder = false;
45245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findString("componentName", &componentName)) {
4525e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        ssize_t index = matchingCodecs.add();
4526e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        OMXCodec::CodecNameAndQuirks *entry = &matchingCodecs.editItemAt(index);
4527e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        entry->mName = String8(componentName.c_str());
4528afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
4529e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        if (!OMXCodec::findCodecQuirks(
4530e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                    componentName.c_str(), &entry->mQuirks)) {
4531e671207115fac3914134c61b336d5fa0242c68caAndreas Huber            entry->mQuirks = 0;
4532afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
45335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
45345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(msg->findString("mime", &mime));
45355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
45365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("encoder", &encoder)) {
45375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder = false;
45385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
45395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
45405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMXCodec::findMatchingCodecs(
45415778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mime.c_str(),
45425778822d86b0337407514b9372562b86edfa91cdAndreas Huber                encoder, // createEncoder
45435778822d86b0337407514b9372562b86edfa91cdAndreas Huber                NULL,  // matchComponentName
45445778822d86b0337407514b9372562b86edfa91cdAndreas Huber                0,     // flags
4545e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                &matchingCodecs);
45465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
45471065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
45481065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    sp<CodecObserver> observer = new CodecObserver;
45491065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    IOMX::node_id node = NULL;
45501065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
45511065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
45521065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            ++matchIndex) {
4553e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        componentName = matchingCodecs.itemAt(matchIndex).mName.string();
4554e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        quirks = matchingCodecs.itemAt(matchIndex).mQuirks;
4555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4556078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        pid_t tid = androidGetTid();
4557078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        int prevPriority = androidGetThreadPriority(tid);
4558078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
45591065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        status_t err = omx->allocateNode(componentName.c_str(), observer, &node);
4560078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, prevPriority);
4561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
45621065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        if (err == OK) {
45631065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            break;
45647a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He        } else {
45657a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He            ALOGW("Allocating component '%s' failed, try next one.", componentName.c_str());
45661065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
45671065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
45681065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        node = NULL;
45691065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    }
45701065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
4571c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    if (node == NULL) {
45725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!mime.empty()) {
45737791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen            ALOGE("Unable to instantiate a %scoder for type '%s'.",
45747791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen                    encoder ? "en" : "de", mime.c_str());
45755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
45767791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen            ALOGE("Unable to instantiate codec '%s'.", componentName.c_str());
45775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
4578c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
4579cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        mCodec->signalError(OMX_ErrorComponentNotFound);
4580c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
4581c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
4582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4583ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    notify = new AMessage(kWhatOMXMessage, mCodec->id());
4584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    observer->setNotificationMessage(notify);
4585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mComponentName = componentName;
4587ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    mCodec->mFlags = 0;
4588ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
4589ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (componentName.endsWith(".secure")) {
4590ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        mCodec->mFlags |= kFlagIsSecure;
45910167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
4592ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
4593ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
4594afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mCodec->mQuirks = quirks;
4595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mOMX = omx;
4596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mNode = node;
4597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
45985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
45995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
4600d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatComponentAllocated);
46015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setString("componentName", mCodec->mComponentName.c_str());
46025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
46035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4604c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4605c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mCodec->changeState(mCodec->mLoadedState);
4606c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4607c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
46085778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
46095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4610c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
4611c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4612c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas HuberACodec::LoadedState::LoadedState(ACodec *codec)
4613c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    : BaseState(codec) {
4614c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4615c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4616c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::stateEntered() {
4617c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
4618c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4619f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mPortEOS[kPortIndexInput] =
4620f6f38287b97ec69b169387add6458f859b770e65Andreas Huber        mCodec->mPortEOS[kPortIndexOutput] = false;
4621f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
4622f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mInputEOSResult = OK;
4623f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
4624054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mDequeueCounter = 0;
4625054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mMetaDataBuffersToSubmit = 0;
4626a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    mCodec->mRepeatFrameDelayUs = -1ll;
4627e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mInputFormat.clear();
4628e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mOutputFormat.clear();
4629054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4630c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (mCodec->mShutdownInProgress) {
4631c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
4632c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4633c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mShutdownInProgress = false;
4634c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mKeepComponentAllocated = false;
4635c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4636c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        onShutdown(keepComponentAllocated);
4637c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
463854b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    mCodec->mExplicitShutdown = false;
4639f393c33e65ae51a7cf168b4e15771b152f996b32Wei Jia
4640f393c33e65ae51a7cf168b4e15771b152f996b32Wei Jia    mCodec->processDeferredMessages();
4641c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4642c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4643c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
4644c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (!keepComponentAllocated) {
4645c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK);
4646c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4647c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->changeState(mCodec->mUninitializedState);
4648c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
4649c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
465054b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    if (mCodec->mExplicitShutdown) {
465154b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        sp<AMessage> notify = mCodec->mNotify->dup();
4652d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
465354b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        notify->post();
465454b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        mCodec->mExplicitShutdown = false;
465554b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    }
4656c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4657c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4658c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
4659c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool handled = false;
4660c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4661c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    switch (msg->what()) {
4662c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatConfigureComponent:
4663c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
4664c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onConfigureComponent(msg);
4665c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
4666c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
4667c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
4668c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
46697cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
46707cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
46717cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            onCreateInputSurface(msg);
46727cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
46737cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
46747cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
46757cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4676c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatStart:
4677c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
4678c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onStart();
4679c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
4680c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
4681c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
4682c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4683c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatShutdown:
4684c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
4685c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
4686c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
4687c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
4688c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
468954b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
4690c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onShutdown(keepComponentAllocated);
4691c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4692c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
4693c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
4694c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
4695c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4696c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatFlush:
4697c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
4698c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4699d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
4700c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->post();
4701c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4702c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
4703c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
4704c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
4705c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4706c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        default:
4707c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            return BaseState::onMessageReceived(msg);
4708c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
4709c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4710c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return handled;
4711c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4712c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4713c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onConfigureComponent(
47145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg) {
47155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onConfigureComponent");
47165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
47175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(mCodec->mNode != NULL);
47185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
47195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString mime;
47205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findString("mime", &mime));
47215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
47225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mCodec->configureCodec(mime.c_str(), msg);
47235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
47245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
4725c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        ALOGE("[%s] configureCodec returning error %d",
4726c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber              mCodec->mComponentName.c_str(), err);
4727c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber
4728251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
4729c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
47305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<RefBase> obj;
4733386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    if (msg->findObject("native-window", &obj)
47345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            && strncmp("OMX.google.", mCodec->mComponentName.c_str(), 11)) {
47351173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        sp<NativeWindowWrapper> nativeWindow(
47361173118eace0e9e347cb007f0da817cee87579edGlenn Kasten                static_cast<NativeWindowWrapper *>(obj.get()));
47371173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        CHECK(nativeWindow != NULL);
47381173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        mCodec->mNativeWindow = nativeWindow->getNativeWindow();
47391ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber
47401ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber        native_window_set_scaling_mode(
47411ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                mCodec->mNativeWindow.get(),
47421ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
4743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((status_t)OK, mCodec->initNativeWindow());
4745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
47465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
47475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
4748d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatComponentConfigured);
4749e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("input-format", mCodec->mInputFormat);
4750e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("output-format", mCodec->mOutputFormat);
47515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
47525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4753c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4754c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
47555778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
47565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
47577cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::LoadedState::onCreateInputSurface(
4758ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        const sp<AMessage> & /* msg */) {
47597cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    ALOGV("onCreateInputSurface");
47607cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
47617cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<AMessage> notify = mCodec->mNotify->dup();
4762d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatInputSurfaceCreated);
47637cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
47647cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<IGraphicBufferProducer> bufferProducer;
47657cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    status_t err;
47667cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
47677cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    err = mCodec->mOMX->createInputSurface(mCodec->mNode, kPortIndexInput,
47687cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            &bufferProducer);
4769a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
4770a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    if (err == OK && mCodec->mRepeatFrameDelayUs > 0ll) {
4771a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        err = mCodec->mOMX->setInternalOption(
4772a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                mCodec->mNode,
4773a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                kPortIndexInput,
4774a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY,
4775a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                &mCodec->mRepeatFrameDelayUs,
4776a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                sizeof(mCodec->mRepeatFrameDelayUs));
4777a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
4778a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (err != OK) {
4779a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            ALOGE("[%s] Unable to configure option to repeat previous "
4780a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  "frames (err %d)",
4781a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  mCodec->mComponentName.c_str(),
4782a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  err);
4783a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
4784a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
4785a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
47862c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    if (err == OK && mCodec->mMaxPtsGapUs > 0ll) {
478794ee4b708acfa941581160b267afb79192b1d816Chong Zhang        err = mCodec->mOMX->setInternalOption(
478894ee4b708acfa941581160b267afb79192b1d816Chong Zhang                mCodec->mNode,
478994ee4b708acfa941581160b267afb79192b1d816Chong Zhang                kPortIndexInput,
479094ee4b708acfa941581160b267afb79192b1d816Chong Zhang                IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP,
479194ee4b708acfa941581160b267afb79192b1d816Chong Zhang                &mCodec->mMaxPtsGapUs,
479294ee4b708acfa941581160b267afb79192b1d816Chong Zhang                sizeof(mCodec->mMaxPtsGapUs));
479394ee4b708acfa941581160b267afb79192b1d816Chong Zhang
479494ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (err != OK) {
479594ee4b708acfa941581160b267afb79192b1d816Chong Zhang            ALOGE("[%s] Unable to configure max timestamp gap (err %d)",
479672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    mCodec->mComponentName.c_str(),
479772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    err);
47982c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
47992c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
48002c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
48012c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    if (err == OK && mCodec->mTimePerCaptureUs > 0ll
48022c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            && mCodec->mTimePerFrameUs > 0ll) {
48032c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        int64_t timeLapse[2];
48042c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[0] = mCodec->mTimePerFrameUs;
48052c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[1] = mCodec->mTimePerCaptureUs;
48062c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        err = mCodec->mOMX->setInternalOption(
48072c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                mCodec->mNode,
48082c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                kPortIndexInput,
48092c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                IOMX::INTERNAL_OPTION_TIME_LAPSE,
48102c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                &timeLapse[0],
48112c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                sizeof(timeLapse));
48122c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
48132c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (err != OK) {
48142c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            ALOGE("[%s] Unable to configure time lapse (err %d)",
48152c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    mCodec->mComponentName.c_str(),
48162c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    err);
48172c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
48182c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
481972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
482072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (err == OK && mCodec->mCreateInputBuffersSuspended) {
482172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        bool suspend = true;
482272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        err = mCodec->mOMX->setInternalOption(
482372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                mCodec->mNode,
482472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                kPortIndexInput,
482572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                IOMX::INTERNAL_OPTION_SUSPEND,
482672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                &suspend,
482772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                sizeof(suspend));
482872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
482972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
483072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("[%s] Unable to configure option to suspend (err %d)",
483194ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  mCodec->mComponentName.c_str(),
483294ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  err);
483394ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
483494ee4b708acfa941581160b267afb79192b1d816Chong Zhang    }
483594ee4b708acfa941581160b267afb79192b1d816Chong Zhang
48367cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err == OK) {
48377cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setObject("input-surface",
48387cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                new BufferProducerWrapper(bufferProducer));
48397cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else {
48407cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // Can't use mCodec->signalError() here -- MediaCodec won't forward
48417cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // the error through because it's in the "configured" state.  We
48427cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // send a kWhatInputSurfaceCreated with an error value instead.
48437cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGE("[%s] onCreateInputSurface returning error %d",
48447cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                mCodec->mComponentName.c_str(), err);
48457cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setInt32("err", err);
48467cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
48477cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->post();
48487cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
48497cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4850c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onStart() {
48515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onStart");
48525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
48535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ(mCodec->mOMX->sendCommand(
48545778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
4855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
4856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->changeState(mCodec->mLoadedToIdleState);
4858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4862f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
4863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4866f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::LoadedToIdleState::stateEntered() {
48673856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
4868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4869cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    status_t err;
4870cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    if ((err = allocateBuffers()) != OK) {
487129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to allocate buffers after transitioning to IDLE state "
4872cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             "(error 0x%08x)",
4873cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             err);
4874cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
4875251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
487691bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber
487791bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber        mCodec->changeState(mCodec->mLoadedState);
4878cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    }
4879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4881f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::LoadedToIdleState::allocateBuffers() {
4882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
4883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
4885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
4886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mCodec->allocateBuffersOnPort(kPortIndexOutput);
4889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4891f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
4892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
489372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
4894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
49006507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
49016507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
49026507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
49036507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
49046507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
49056507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
49066463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatResume:
49076463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
49086463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We'll be active soon enough.
49096463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
49106463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
49116463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
49126463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatFlush:
49136463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
49146463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We haven't even started yet, so we're flushed alright...
49156463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            sp<AMessage> notify = mCodec->mNotify->dup();
4916d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
49176463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->post();
49186463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
49196463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
49206463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
4921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
4923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4926f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onOMXEvent(
4927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
4933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
4935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting),
4936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
4937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mIdleToExecutingState);
4939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4950f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
4951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4954f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToExecutingState::stateEntered() {
49553856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
4956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4958f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
4959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
496072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
4961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4967d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatResume:
4968d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
4969d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We'll be active soon enough.
4970d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
4971d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
4972d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
4973d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatFlush:
4974d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
4975d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We haven't even started yet, so we're flushed alright...
4976d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4977d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
4978d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->post();
4979d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
4980d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
4981d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
4982d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
49836507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
49846507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
49856507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
49866507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
49876507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
49886507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
4989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
4991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4994f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onOMXEvent(
4995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
5000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateExecuting);
5001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mExecutingState->resume();
5003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingState);
5004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5015f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingState::ExecutingState(ACodec *codec)
5016349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    : BaseState(codec),
5017349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber      mActive(false) {
5018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5020f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
5021ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
5022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
5023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5025054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputMetaBuffers() {
5026054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // submit as many buffers as there are input buffers with the codec
5027054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // in case we are in port reconfiguring
5028054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
5029054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
5030054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5031054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) {
5032054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            if (mCodec->submitOutputMetaDataBuffer() != OK)
5033054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                break;
5034054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
5035054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
50364dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
50374dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
50384dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
5039054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
5040054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5041054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitRegularOutputBuffers() {
5042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
5043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
5044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mCodec->mNativeWindow != NULL) {
5046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(info->mStatus == BufferInfo::OWNED_BY_US
5047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
5048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
5050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                continue;
5051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
5053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
5054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
50563856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] calling fillBuffer %p",
5057349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str(), info->mBufferID);
5058349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
5060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
5061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
5063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5066054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputBuffers() {
5067c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar    submitRegularOutputBuffers();
5068054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mCodec->mStoreMetaDataInOutputBuffers) {
5069054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        submitOutputMetaBuffers();
5070054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
5071054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
5072054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5073f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::resume() {
5074349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    if (mActive) {
50753856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] We're already active, no need to resume.",
5076349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str());
5077349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5078349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        return;
5079349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    }
5080349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5081f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    submitOutputBuffers();
5082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
50833cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    // Post all available input buffers
5084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_GT(mCodec->mBuffers[kPortIndexInput].size(), 0u);
50853cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); i++) {
50863cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
50873cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_US) {
50883cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar            postFillThisBuffer(info);
50893cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        }
50903cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    }
5091349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5092349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    mActive = true;
5093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5094f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5095f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::stateEntered() {
50963856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
5097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->processDeferredMessages();
5099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5101f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
5102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5107c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
5108c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
5109c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
5110c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5111c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mShutdownInProgress = true;
511254b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
5113c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mKeepComponentAllocated = keepComponentAllocated;
5114c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5115349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
5116349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
5118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
5119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
5120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingToIdleState);
5122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
51297a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong            ALOGV("[%s] ExecutingState flushing now "
5130d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                 "(codec owns %d/%d input, %d/%d output).",
5131d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mComponentName.c_str(),
5132d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
5133d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexInput].size(),
5134d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
5135d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexOutput].size());
5136d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
5137349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
5138349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
5140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandFlush, OMX_ALL),
5141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
5142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mFlushingState);
5144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatResume:
5149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            resume();
5151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5156496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
5157496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
5158496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            status_t err = mCodec->requestIDRFrame();
5159496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            if (err != OK) {
5160496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                ALOGW("Requesting an IDR frame failed.");
5161496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            }
5162496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5163496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            handled = true;
5164496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
5165496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
5166496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5167a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
5168a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
5169a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
5170a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
5171a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5172a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = mCodec->setParameters(params);
5173a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5174a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> reply;
5175a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            if (msg->findMessage("reply", &reply)) {
5176a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->setInt32("err", err);
5177a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->post();
5178a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            }
5179a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5180a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            handled = true;
5181a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
5182a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
5183a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
51847cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
51857cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
51866507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
51877cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
51887cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
51897cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
51907cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
51914dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
51924dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        case kWhatSubmitOutputMetaDataBufferIfEOS:
51934dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        {
51944dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            if (mCodec->mPortEOS[kPortIndexInput] &&
51954dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    !mCodec->mPortEOS[kPortIndexOutput]) {
51964dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                status_t err = mCodec->submitOutputMetaDataBuffer();
51974dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                if (err == OK) {
51984dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
51994dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                }
52004dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            }
52014dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            return true;
52024dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        }
52034dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
5204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5212a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t ACodec::setParameters(const sp<AMessage> &params) {
5213a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    int32_t videoBitrate;
5214530fdbdc1b5491f3fbf172752834d1515701e142Lajos Molnar    if (params->findInt32("video-bitrate", &videoBitrate)) {
5215a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        OMX_VIDEO_CONFIG_BITRATETYPE configParams;
5216a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        InitOMXParams(&configParams);
5217a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nPortIndex = kPortIndexOutput;
5218a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nEncodeBitrate = videoBitrate;
5219a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5220a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        status_t err = mOMX->setConfig(
5221a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                mNode,
5222a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                OMX_IndexConfigVideoBitrate,
5223a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                &configParams,
5224a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                sizeof(configParams));
5225a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5226a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        if (err != OK) {
5227a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
5228a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                   videoBitrate, err);
5229a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5230a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            return err;
5231a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
5232a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    }
5233a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
523472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    int64_t skipFramesBeforeUs;
523572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (params->findInt64("skip-frames-before", &skipFramesBeforeUs)) {
523672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        status_t err =
523772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mOMX->setInternalOption(
523872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     mNode,
523972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     kPortIndexInput,
524072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     IOMX::INTERNAL_OPTION_START_TIME,
524172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     &skipFramesBeforeUs,
524272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     sizeof(skipFramesBeforeUs));
524372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
524472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
524572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("Failed to set parameter 'skip-frames-before' (err %d)", err);
524672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            return err;
524772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
524872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
524972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
5250e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    int32_t dropInputFrames;
5251e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    if (params->findInt32("drop-input-frames", &dropInputFrames)) {
5252e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        bool suspend = dropInputFrames != 0;
5253e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
5254b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err =
5255b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            mOMX->setInternalOption(
5256e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     mNode,
5257e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     kPortIndexInput,
5258e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     IOMX::INTERNAL_OPTION_SUSPEND,
5259e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     &suspend,
5260b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber                     sizeof(suspend));
5261b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
5262b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
5263b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err);
5264b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
5265b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
5266b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    }
5267b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
5268b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    int32_t dummy;
5269b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    if (params->findInt32("request-sync", &dummy)) {
5270b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err = requestIDRFrame();
5271b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
5272b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
5273b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Requesting a sync frame failed w/ err %d", err);
5274b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
5275b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
5276e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    }
5277e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
5278a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return OK;
5279a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
5280a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
52816507d14c6d10f93d390de62b9eed267f9b544985Andy McFaddenvoid ACodec::onSignalEndOfInputStream() {
52826507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    sp<AMessage> notify = mNotify->dup();
5283d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatSignaledInputEOS);
52846507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
52856507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    status_t err = mOMX->signalEndOfInputStream(mNode);
52866507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    if (err != OK) {
52876507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        notify->setInt32("err", err);
52886507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    }
52896507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->post();
52906507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden}
52916507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
5292f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onOMXEvent(
5293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventPortSettingsChanged:
5296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
5298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
529931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
5300054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mCodec->mMetaDataBuffersToSubmit = 0;
5301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
5302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
5303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_CommandPortDisable, kPortIndexOutput),
5304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
5305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5306349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                mCodec->freeOutputBuffersNotOwnedByComponent();
5307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
530931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            } else if (data2 == OMX_IndexConfigCommonOutputCrop) {
531031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
5311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
53123856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08lx",
5313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->mComponentName.c_str(), data2);
5314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventBufferFlag:
5320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5331f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
5332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ACodec *codec)
5333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5336f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
5337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
5338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput) {
5339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return FREE_BUFFERS;
5340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
5343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
5345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5347f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onMessageReceived(
5348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
5349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5354349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case kWhatResume:
5355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5356349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            if (msg->what() == kWhatResume) {
53573856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
5358349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            }
5359349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
5361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5373f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::OutputPortSettingsChangedState::stateEntered() {
53743856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now handling output port settings change",
5375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mCodec->mComponentName.c_str());
5376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5378f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onOMXEvent(
5379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
5384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
5385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
53863856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now disabled.",
5387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
5388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mCodec->mBuffers[kPortIndexOutput].isEmpty());
5390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mDealer[kPortIndexOutput].clear();
5391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
5393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput),
5394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
5395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5396cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                status_t err;
5397cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                if ((err = mCodec->allocateBuffersOnPort(
5398cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                                kPortIndexOutput)) != OK) {
539929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("Failed to allocate output port buffers after "
5400cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         "port reconfiguration (error 0x%08x)",
5401cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         err);
5402cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
5403251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5404d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
5405755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // This is technically not correct, but appears to be
5406755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the only way to free the component instance.
5407755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // Controlled transitioning from excecuting->idle
5408755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // and idle->loaded seem impossible probably because
5409755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the output port never finishes re-enabling.
5410755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mShutdownInProgress = true;
5411755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mKeepComponentAllocated = false;
5412755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->changeState(mCodec->mLoadedState);
5413cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                }
5414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
5416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
5417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
5418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
541931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
542031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
54213856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now reenabled.",
5422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
5423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5424349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                if (mCodec->mExecutingState->active()) {
5425349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    mCodec->mExecutingState->submitOutputBuffers();
5426349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                }
5427349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mExecutingState);
5429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
5431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
5434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
5438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5443f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
54445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : BaseState(codec),
54455778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mComponentNowIdle(false) {
5446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5448f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
5449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
5455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
5456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
5457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
5463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5476f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::stateEntered() {
54773856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
547831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
54795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mComponentNowIdle = false;
548031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mCodec->mSentFormat = false;
5481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5483f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onOMXEvent(
5484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
5489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
5490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
54915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mComponentNowIdle = true;
54925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            changeStateIfWeOwnAllBuffers();
5494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5498349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
5499349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventBufferFlag:
5500349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
5501349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We're shutting down and don't care about this anymore.
5502349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
5503349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
5504349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
55090af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
5510f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
55115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
5512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->sendCommand(
5513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded),
5514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
5515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexInput), (status_t)OK);
5517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexOutput), (status_t)OK);
5518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
55190167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown)
55200167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && mCodec->mNativeWindow != NULL) {
5521bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // We push enough 1x1 blank buffers to ensure that one of
5522bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // them has made it to the display.  This allows the OMX
5523bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // component teardown to zero out any protected buffers
5524bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // without the risk of scanning out one of those buffers.
5525bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            mCodec->pushBlankBuffersToNativeWindow();
5526bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
5527bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
5528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mIdleToLoadedState);
5529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5532f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onInputBufferFilled(
5533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
5534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
5535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
5537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5539f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onOutputBufferDrained(
5540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
5541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
5542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
5544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5548f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
5549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5552f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
5553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
5559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
5567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
5568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
5569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5580f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToLoadedState::stateEntered() {
55813856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
5582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5584f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onOMXEvent(
5585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
5590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateLoaded);
5591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5592c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->changeState(mCodec->mLoadedState);
5593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5604f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::FlushingState::FlushingState(ACodec *codec)
5605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5608f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::stateEntered() {
56093856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
5610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
5612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5614f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
5615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
5621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing this right now.
5627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5639f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onOMXEvent(
5640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
56417a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] FlushingState onOMXEvent(%d,%ld)",
5642d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            mCodec->mComponentName.c_str(), event, data1);
5643d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
5644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandFlush);
5648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
5650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(!mFlushComplete[data2]);
5651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mFlushComplete[data2] = true;
5652e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber
5653e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                if (mFlushComplete[kPortIndexInput]
5654e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                        && mFlushComplete[kPortIndexOutput]) {
5655e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                    changeStateIfWeOwnAllBuffers();
5656e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                }
5657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
5658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, OMX_ALL);
5659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexInput]);
5660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexOutput]);
5661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                changeStateIfWeOwnAllBuffers();
5663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5668349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
5669349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
5670349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec->id());
5671349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("type", omx_message::EVENT);
5672609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            msg->setInt32("node", mCodec->mNode);
5673349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("event", event);
5674349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data1", data1);
5675349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data2", data2);
5676349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
56773856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
5678349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                 mCodec->mComponentName.c_str());
5679349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5680349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mCodec->deferMessage(msg);
5681349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5682349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
5683349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
5684349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
5690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5692f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
5693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
5694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
5696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5698f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
5699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
5700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
5702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5704f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
5705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mFlushComplete[kPortIndexInput]
5706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mFlushComplete[kPortIndexOutput]
5707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mCodec->allYourBuffersAreBelongToUs()) {
57087e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // We now own all buffers except possibly those still queued with
57097e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // the native window for rendering. Let's get those back as well.
57107e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
57117e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
5712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
5713d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatFlushCompleted);
5714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->post();
5715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->mPortEOS[kPortIndexInput] =
5717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mPortEOS[kPortIndexOutput] = false;
5718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5719dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber        mCodec->mInputEOSResult = OK;
5720dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
5721f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        if (mCodec->mSkipCutBuffer != NULL) {
5722f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen            mCodec->mSkipCutBuffer->clear();
5723f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        }
5724f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen
5725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mExecutingState);
5726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
5730