ACodec.cpp revision cc7cc67349b7a3f498882087aa42ffc05a2daf11
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
271de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar#include <gui/Surface.h>
281de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar
29f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/ACodec.h>
30f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <binder/MemoryDealer.h>
32f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/hexdump.h>
34f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ABuffer.h>
35f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ADebug.h>
36f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/AMessage.h>
37a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar#include <media/stagefright/foundation/AUtils.h>
38f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
397cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden#include <media/stagefright/BufferProducerWrapper.h>
40afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber#include <media/stagefright/MediaCodecList.h>
41f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaDefs.h>
42f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/OMXClient.h>
431065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber#include <media/stagefright/OMXCodec.h>
44d291c222357303b9611cab89d0c3b047584ef377Chong Zhang#include <media/stagefright/PersistentSurface.h>
45b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar#include <media/stagefright/SurfaceUtils.h>
463a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber#include <media/hardware/HardwareAPI.h>
473a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
4897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu#include <OMX_AudioExt.h>
494154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev#include <OMX_VideoExt.h>
50f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <OMX_Component.h>
5197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu#include <OMX_IndexExt.h>
52777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim#include <OMX_AsString.h>
53f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
54496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#include "include/avc_utils.h"
55496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
56f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android {
57f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
58251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// OMX errors are directly mapped into status_t range if
59251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// there is no corresponding MediaError status code.
60251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Use the statusFromOMXError(int32_t omxError) function.
61251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung//
62251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Currently this is a direct map.
63251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// See frameworks/native/include/media/openmax/OMX_Core.h
64251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung//
65251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Vendor OMX errors     from 0x90000000 - 0x9000FFFF
66251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Extension OMX errors  from 0x8F000000 - 0x90000000
67251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Standard OMX errors   from 0x80001000 - 0x80001024 (0x80001024 current)
68251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung//
69251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
70251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// returns true if err is a recognized OMX error code.
71251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// as OMX error is OMX_S32, this is an int32_t type
72251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hungstatic inline bool isOMXError(int32_t err) {
73251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    return (ERROR_CODEC_MIN <= err && err <= ERROR_CODEC_MAX);
74251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung}
75251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
76251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// converts an OMX error to a status_t
77251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hungstatic inline status_t statusFromOMXError(int32_t omxError) {
78251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    switch (omxError) {
79251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case OMX_ErrorInvalidComponentName:
80251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case OMX_ErrorComponentNotFound:
81251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return NAME_NOT_FOUND; // can trigger illegal argument error for provided names.
82251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    default:
83251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return isOMXError(omxError) ? omxError : 0; // no translation required
84251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
85251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung}
86251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
87251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// checks and converts status_t to a non-side-effect status_t
88251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hungstatic inline status_t makeNoSideEffectStatus(status_t err) {
89251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    switch (err) {
90251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // the following errors have side effects and may come
91251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // from other code modules. Remap for safety reasons.
92251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case INVALID_OPERATION:
93251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case DEAD_OBJECT:
94251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return UNKNOWN_ERROR;
95251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    default:
96251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return err;
97251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
98251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung}
99251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
100f933441648ef6a71dee783d733aac17b9508b452Andreas Hubertemplate<class T>
101f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic void InitOMXParams(T *params) {
102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nSize = sizeof(T);
103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nVersionMajor = 1;
104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nVersionMinor = 0;
105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nRevision = 0;
106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nStep = 0;
107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
109f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct CodecObserver : public BnOMXObserver {
110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CodecObserver() {}
111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void setNotificationMessage(const sp<AMessage> &msg) {
113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mNotify = msg;
114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // from IOMXObserver
117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onMessage(const omx_message &omx_msg) {
118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> msg = mNotify->dup();
119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->setInt32("type", omx_msg.type);
121609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        msg->setInt32("node", omx_msg.node);
122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        switch (omx_msg.type) {
124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::EVENT:
125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("event", omx_msg.u.event_data.event);
127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("data1", omx_msg.u.event_data.data1);
128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("data2", omx_msg.u.event_data.data2);
129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::EMPTY_BUFFER_DONE:
133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
134609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                msg->setInt32("buffer", omx_msg.u.buffer_data.buffer);
135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::FILL_BUFFER_DONE:
139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
140609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                msg->setInt32(
141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "buffer", omx_msg.u.extended_buffer_data.buffer);
142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "range_offset",
144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.range_offset);
145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "range_length",
147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.range_length);
148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "flags",
150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.flags);
151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt64(
152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "timestamp",
153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.timestamp);
154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            default:
158777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                ALOGE("Unrecognized message type: %d", omx_msg.type);
159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->post();
163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
165f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual ~CodecObserver() {}
167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
168f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> mNotify;
170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(CodecObserver);
172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
176f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::BaseState : public AState {
177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState(ACodec *codec, const sp<AState> &parentState = NULL);
178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
179f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    enum PortMode {
181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        KEEP_BUFFERS,
182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        RESUBMIT_BUFFERS,
183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        FREE_BUFFERS,
184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ACodec *mCodec;
187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void postFillThisBuffer(BufferInfo *info);
198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
199f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXMessage(const sp<AMessage> &msg);
201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXEmptyBufferDone(IOMX::buffer_id bufferID);
203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXFillBufferDone(
205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID,
206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            size_t rangeOffset, size_t rangeLength,
207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            OMX_U32 flags,
208784e24e386b088c05d653ab482f2e95cb53e3d01Andy Hung            int64_t timeUs);
209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void getMoreInputDataIfPossible();
211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(BaseState);
213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
217ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberstruct ACodec::DeathNotifier : public IBinder::DeathRecipient {
218ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    DeathNotifier(const sp<AMessage> &notify)
219ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        : mNotify(notify) {
220ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
221ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
222ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual void binderDied(const wp<IBinder> &) {
223ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mNotify->post();
224ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
225ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
226ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprotected:
227ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual ~DeathNotifier() {}
228ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
229ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprivate:
230ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> mNotify;
231ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
232ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(DeathNotifier);
233ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber};
234ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
235f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::UninitializedState : public ACodec::BaseState {
236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    UninitializedState(ACodec *codec);
237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
238f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
240c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
242f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void onSetup(const sp<AMessage> &msg);
244c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onAllocateComponent(const sp<AMessage> &msg);
245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
246ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<DeathNotifier> mDeathNotifier;
247ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(UninitializedState);
249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
253c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberstruct ACodec::LoadedState : public ACodec::BaseState {
254c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    LoadedState(ACodec *codec);
255c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
256c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprotected:
257c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
258c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
259c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
260c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprivate:
261c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    friend struct ACodec::UninitializedState;
262c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
263c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onConfigureComponent(const sp<AMessage> &msg);
2647cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    void onCreateInputSurface(const sp<AMessage> &msg);
2658f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang    void onSetInputSurface(const sp<AMessage> &msg);
266c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onStart();
267c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onShutdown(bool keepComponentAllocated);
268c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
269d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    status_t setupInputSurface();
270d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
271c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedState);
272c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber};
273c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
274c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
275c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
276f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::LoadedToIdleState : public ACodec::BaseState {
277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    LoadedToIdleState(ACodec *codec);
278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
279f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
284f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t allocateBuffers();
286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedToIdleState);
288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
292f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToExecutingState : public ACodec::BaseState {
293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToExecutingState(ACodec *codec);
294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
295f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
300f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToExecutingState);
302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
306f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingState : public ACodec::BaseState {
307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingState(ACodec *codec);
308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
309054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitRegularOutputBuffers();
310054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitOutputMetaBuffers();
311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void submitOutputBuffers();
312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Submit output buffers to the decoder, submit input buffers to client
314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // to fill with data.
315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void resume();
316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
317349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    // Returns true iff input and output buffers are in play.
318349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool active() const { return mActive; }
319349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
320f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
327f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
328349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool mActive;
329349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingState);
331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
335f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::OutputPortSettingsChangedState : public ACodec::BaseState {
336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OutputPortSettingsChangedState(ACodec *codec);
337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
338f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
345f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(OutputPortSettingsChangedState);
347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
351f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingToIdleState : public ACodec::BaseState {
352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingToIdleState(ACodec *codec);
353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
354f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
363f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool mComponentNowIdle;
3675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingToIdleState);
369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
373f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToLoadedState : public ACodec::BaseState {
374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToLoadedState(ACodec *codec);
375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
376f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
382f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToLoadedState);
384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
388f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::FlushingState : public ACodec::BaseState {
389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    FlushingState(ACodec *codec);
390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
391f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
400f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool mFlushComplete[2];
402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(FlushingState);
406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
410f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ACodec()
411afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    : mQuirks(0),
412609b815a3131d22da38b2f452faa9f89daad4039Andy Hung      mNode(0),
4135778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mSentFormat(false),
4148db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu      mIsVideo(false),
415c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber      mIsEncoder(false),
416308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang      mUseMetadataOnEncoderOutput(false),
4179806555d3930be43e11106281dee354820ac1c88Andreas Huber      mShutdownInProgress(false),
41854b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar      mExplicitShutdown(false),
4199806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderDelay(0),
4209806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderPadding(0),
421e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang      mRotationDegrees(0),
4229806555d3930be43e11106281dee354820ac1c88Andreas Huber      mChannelMaskPresent(false),
423054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mChannelMask(0),
424054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mDequeueCounter(0),
425054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mStoreMetaDataInOutputBuffers(false),
426011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar      mLegacyAdaptiveExperiment(false),
427a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber      mMetaDataBuffersToSubmit(0),
42894ee4b708acfa941581160b267afb79192b1d816Chong Zhang      mRepeatFrameDelayUs(-1ll),
4292c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang      mMaxPtsGapUs(-1ll),
43037b2b389139ed638831e49708c947863eef631efRonghua Wu      mMaxFps(-1),
4312c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang      mTimePerFrameUs(-1ll),
432609b815a3131d22da38b2f452faa9f89daad4039Andy Hung      mTimePerCaptureUs(-1ll),
433ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad      mCreateInputBuffersSuspended(false),
434ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad      mTunneled(false) {
435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mUninitializedState = new UninitializedState(this);
436c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mLoadedState = new LoadedState(this);
437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mLoadedToIdleState = new LoadedToIdleState(this);
438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToExecutingState = new IdleToExecutingState(this);
439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingState = new ExecutingState(this);
440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOutputPortSettingsChangedState =
442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        new OutputPortSettingsChangedState(this);
443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingToIdleState = new ExecutingToIdleState(this);
445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToLoadedState = new IdleToLoadedState(this);
446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushingState = new FlushingState(this);
447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
449dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber    mInputEOSResult = OK;
450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeState(mUninitializedState);
452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
454f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::~ACodec() {
455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
457f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::setNotificationMessage(const sp<AMessage> &msg) {
458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mNotify = msg;
459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
461f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::initiateSetup(const sp<AMessage> &msg) {
462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setWhat(kWhatSetup);
4631d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    msg->setTarget(this);
464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
467a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Hubervoid ACodec::signalSetParameters(const sp<AMessage> &params) {
4681d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetParameters, this);
469a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->setMessage("params", params);
470a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->post();
471a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
472a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4735778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateAllocateComponent(const sp<AMessage> &msg) {
4745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatAllocateComponent);
4751d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    msg->setTarget(this);
4765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4775778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4795778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateConfigureComponent(const sp<AMessage> &msg) {
4805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatConfigureComponent);
4811d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    msg->setTarget(this);
4825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4835778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4851dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t ACodec::setSurface(const sp<Surface> &surface) {
4861dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetSurface, this);
4871dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    msg->setObject("surface", surface);
4881dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
4891dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    sp<AMessage> response;
4901dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    status_t err = msg->postAndAwaitResponse(&response);
4911dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
4921dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err == OK) {
4931dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        (void)response->findInt32("err", &err);
4941dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
4951dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    return err;
4961dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar}
4971dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
4987cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::initiateCreateInputSurface() {
4991d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatCreateInputSurface, this))->post();
5007cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
5017cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
5028f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhangvoid ACodec::initiateSetInputSurface(
503d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        const sp<PersistentSurface> &surface) {
5048f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang    sp<AMessage> msg = new AMessage(kWhatSetInputSurface, this);
505d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    msg->setObject("input-surface", surface);
506d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    msg->post();
507d291c222357303b9611cab89d0c3b047584ef377Chong Zhang}
508d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5097cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::signalEndOfInputStream() {
5101d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatSignalEndOfInputStream, this))->post();
5117cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
5127cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
5135778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateStart() {
5141d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatStart, this))->post();
5155778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
5165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
517f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalFlush() {
5187a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] signalFlush", mComponentName.c_str());
5191d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatFlush, this))->post();
520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
522f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalResume() {
5231d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatResume, this))->post();
524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
526c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::initiateShutdown(bool keepComponentAllocated) {
5271d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatShutdown, this);
528c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->setInt32("keepComponentAllocated", keepComponentAllocated);
529c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->post();
53030358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar    if (!keepComponentAllocated) {
53130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        // ensure shutdown completes in 3 seconds
5321d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar        (new AMessage(kWhatReleaseCodecInstance, this))->post(3000000);
53330358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar    }
534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
536496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubervoid ACodec::signalRequestIDRFrame() {
5371d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatRequestIDRFrame, this))->post();
538496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
539496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5404dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
5414dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// Some codecs may return input buffers before having them processed.
5424dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// This causes a halt if we already signaled an EOS on the input
5434dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// port.  For now keep submitting an output buffer if there was an
5444dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// EOS on the input port, but not yet on the output port.
5454dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnarvoid ACodec::signalSubmitOutputMetaDataBufferIfEOS_workaround() {
5464dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    if (mPortEOS[kPortIndexInput] && !mPortEOS[kPortIndexOutput] &&
5474dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            mMetaDataBuffersToSubmit > 0) {
5481d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar        (new AMessage(kWhatSubmitOutputMetaDataBufferIfEOS, this))->post();
5494dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    }
5504dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar}
5514dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
5521dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t ACodec::handleSetSurface(const sp<Surface> &surface) {
5531dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // allow keeping unset surface
5541dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (surface == NULL) {
5551dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        if (mNativeWindow != NULL) {
5561dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            ALOGW("cannot unset a surface");
5571dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            return INVALID_OPERATION;
5581dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
5591dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return OK;
5601dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
5611dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
5621dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // allow keeping unset surface
5631dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mNativeWindow == NULL) {
5641dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGW("component was not configured with a surface");
5651dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return INVALID_OPERATION;
5661dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
5671dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
5681dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    ANativeWindow *nativeWindow = surface.get();
5691dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // if we have not yet started the codec, we can simply set the native window
5701dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mBuffers[kPortIndexInput].size() == 0) {
5711dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        mNativeWindow = surface;
5721dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return OK;
5731dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
5741dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
5751dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // we do not support changing a tunneled surface after start
5761dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mTunneled) {
5771dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGW("cannot change tunneled surface");
5781dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return INVALID_OPERATION;
5791dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
5801dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
5811dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    status_t err = setupNativeWindowSizeFormatAndUsage(nativeWindow);
5821dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != OK) {
5831dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
5841dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
5851dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
5861dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // get min undequeued count. We cannot switch to a surface that has a higher
5871dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // undequeued count than we allocated.
5881dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    int minUndequeuedBuffers = 0;
5891dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    err = nativeWindow->query(
5901dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            nativeWindow, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
5911dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            &minUndequeuedBuffers);
5921dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != 0) {
5931dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
5941dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                strerror(-err), -err);
5951dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
5961dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
5971dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (minUndequeuedBuffers > (int)mNumUndequeuedBuffers) {
5981dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGE("new surface holds onto more buffers (%d) than planned for (%zu)",
5991dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                minUndequeuedBuffers, mNumUndequeuedBuffers);
6001dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return BAD_VALUE;
6011dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6021dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
6031dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // we cannot change the number of output buffers while OMX is running
6041dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // set up surface to the same count
6051dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    Vector<BufferInfo> &buffers = mBuffers[kPortIndexOutput];
6061dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    ALOGV("setting up surface for %zu buffers", buffers.size());
6071dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
6081dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    err = native_window_set_buffer_count(nativeWindow, buffers.size());
6091dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != 0) {
6101dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
6111dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                -err);
6121dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
6131dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6141dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
615dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    // need to enable allocation when attaching
616dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    surface->getIGraphicBufferProducer()->allowAllocation(true);
617dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar
6181dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // for meta data mode, we move dequeud buffers to the new surface.
6191dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // for non-meta mode, we must move all registered buffers
6201dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    for (size_t i = 0; i < buffers.size(); ++i) {
6211dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        const BufferInfo &info = buffers[i];
6221dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        // skip undequeued buffers for meta data mode
6231dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        if (mStoreMetaDataInOutputBuffers
624011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                && !mLegacyAdaptiveExperiment
6251dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                && info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
6261dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            ALOGV("skipping buffer %p", info.mGraphicBuffer->getNativeBuffer());
6271dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            continue;
6281dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
6291dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGV("attaching buffer %p", info.mGraphicBuffer->getNativeBuffer());
6301dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
6311dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        err = surface->attachBuffer(info.mGraphicBuffer->getNativeBuffer());
6321dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        if (err != OK) {
6331dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            ALOGE("failed to attach buffer %p to the new surface: %s (%d)",
6341dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    info.mGraphicBuffer->getNativeBuffer(),
6351dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    strerror(-err), -err);
6361dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            return err;
6371dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
6381dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6391dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
6401dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // cancel undequeued buffers to new surface
641011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar    if (!mStoreMetaDataInOutputBuffers || mLegacyAdaptiveExperiment) {
6421dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        for (size_t i = 0; i < buffers.size(); ++i) {
6431dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            const BufferInfo &info = buffers[i];
6441dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
6451dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                ALOGV("canceling buffer %p", info.mGraphicBuffer->getNativeBuffer());
6461dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                err = nativeWindow->cancelBuffer(
6471dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                        nativeWindow, info.mGraphicBuffer->getNativeBuffer(), -1);
6481dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                if (err != OK) {
6491dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    ALOGE("failed to cancel buffer %p to the new surface: %s (%d)",
6501dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                            info.mGraphicBuffer->getNativeBuffer(),
6511dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                            strerror(-err), -err);
6521dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    return err;
6531dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                }
6541dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            }
6551dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
6561dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        // disallow further allocation
6571dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        (void)surface->getIGraphicBufferProducer()->allowAllocation(false);
6581dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6591dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
660484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar    // push blank buffers to previous window if requested
661484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar    if (mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown) {
662484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar        pushBlankBuffersToNativeWindow(mNativeWindow.get());
663484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar    }
664484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar
6651dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    mNativeWindow = nativeWindow;
6661dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    return OK;
6671dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar}
6681dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
669f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mDealer[portIndex] == NULL);
673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mBuffers[portIndex].isEmpty());
674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
677054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (mStoreMetaDataInOutputBuffers) {
678054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputMetaDataBuffers();
679054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
680054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputBuffersFromNativeWindow();
681054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
6825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
6835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
6845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
6855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = portIndex;
686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
6885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err == OK) {
691609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGV("[%s] Allocating %u buffers of size %u on %s port",
6925778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mComponentName.c_str(),
6935778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    def.nBufferCountActual, def.nBufferSize,
6945778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    portIndex == kPortIndexInput ? "input" : "output");
695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            size_t totalSize = def.nBufferCountActual * def.nBufferSize;
6975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
7005778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
7015581770ee0dde70e2e9c50533be35e537a5800efChong Zhang                if (mem == NULL || mem->pointer() == NULL) {
702777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return NO_MEMORY;
703777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
705ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                BufferInfo info;
706ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                info.mStatus = BufferInfo::OWNED_BY_US;
707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
708afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                uint32_t requiresAllocateBufferBit =
709afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                    (portIndex == kPortIndexInput)
710afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        ? OMXCodec::kRequiresAllocateBufferOnInputPorts
711afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        : OMXCodec::kRequiresAllocateBufferOnOutputPorts;
7121065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
713308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                if ((portIndex == kPortIndexInput && (mFlags & kFlagIsSecure))
714308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        || mUseMetadataOnEncoderOutput) {
715ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    mem.clear();
716ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
717ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    void *ptr;
718ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->allocateBuffer(
719ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, def.nBufferSize, &info.mBufferID,
720ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            &ptr);
721ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
722308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    int32_t bufSize = mUseMetadataOnEncoderOutput ?
723308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                            (4 + sizeof(buffer_handle_t)) : def.nBufferSize;
724308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
725308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    info.mData = new ABuffer(ptr, bufSize);
726ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                } else if (mQuirks & requiresAllocateBufferBit) {
7275778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    err = mOMX->allocateBufferWithBackup(
728cc7cc67349b7a3f498882087aa42ffc05a2daf11Lajos Molnar                            mNode, portIndex, mem, &info.mBufferID, def.nBufferSize);
7295778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
730cc7cc67349b7a3f498882087aa42ffc05a2daf11Lajos Molnar                    err = mOMX->useBuffer(mNode, portIndex, mem, &info.mBufferID, def.nBufferSize);
731ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                }
732ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
733ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                if (mem != NULL) {
734ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    info.mData = new ABuffer(mem->pointer(), def.nBufferSize);
7355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
7361065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
7375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mBuffers[portIndex].push(info);
7381065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            }
7391065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
7405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
7435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
7445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> notify = mNotify->dup();
747d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatBuffersAllocated);
7485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("portIndex", portIndex);
750eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
751eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    sp<PortDescription> desc = new PortDescription;
752eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
7535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
754eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        const BufferInfo &info = mBuffers[portIndex][i];
7555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
756eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        desc->addBuffer(info.mBufferID, info.mData);
757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
759eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    notify->setObject("portDesc", desc);
7605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->post();
7615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7651dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t ACodec::setupNativeWindowSizeFormatAndUsage(ANativeWindow *nativeWindow /* nonnull */) {
7661dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    OMX_PARAM_PORTDEFINITIONTYPE def;
7671dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    InitOMXParams(&def);
7681dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    def.nPortIndex = kPortIndexOutput;
7691dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
7701dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    status_t err = mOMX->getParameter(
7711dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
7721dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
7731dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != OK) {
7741dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
7751dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7761dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
7771dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    OMX_U32 usage = 0;
7781dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
7791dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != 0) {
7801dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGW("querying usage flags from OMX IL component failed: %d", err);
7811dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        // XXX: Currently this error is logged, but not fatal.
7821dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        usage = 0;
7831dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7841dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    int omxUsage = usage;
7851dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
7861dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mFlags & kFlagIsGrallocUsageProtected) {
7871dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        usage |= GRALLOC_USAGE_PROTECTED;
7881dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7891dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
790b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar    usage |= GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP;
791b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar
7921dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    ALOGV("gralloc usage: %#x(OMX) => %#x(ACodec)", omxUsage, usage);
7931dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    return setNativeWindowSizeFormatAndUsage(
7941dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            nativeWindow,
7951dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            def.format.video.nFrameWidth,
7961dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            def.format.video.nFrameHeight,
7971dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            def.format.video.eColorFormat,
7981dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            mRotationDegrees,
7991dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            usage);
8001dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar}
8011dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
8021dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t ACodec::configureOutputBuffersFromNativeWindow(
8031dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        OMX_U32 *bufferCount, OMX_U32 *bufferSize,
8041dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        OMX_U32 *minUndequeuedBuffers) {
8051dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    OMX_PARAM_PORTDEFINITIONTYPE def;
8061dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    InitOMXParams(&def);
8071dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    def.nPortIndex = kPortIndexOutput;
8081dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
8091dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    status_t err = mOMX->getParameter(
8101dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
8111dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
8121dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err == OK) {
8131dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        err = setupNativeWindowSizeFormatAndUsage(mNativeWindow.get());
8141dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
8151dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != OK) {
8161dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
8171dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
8181dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
819ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // Exits here for tunneled video playback codecs -- i.e. skips native window
820ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // buffer allocation step as this is managed by the tunneled OMX omponent
821ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // itself and explicitly sets def.nBufferCountActual to 0.
822ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    if (mTunneled) {
823ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        ALOGV("Tunneled Playback: skipping native window buffer allocation.");
824ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        def.nBufferCountActual = 0;
825ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        err = mOMX->setParameter(
826ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
827ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
828ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *minUndequeuedBuffers = 0;
829ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *bufferCount = 0;
830ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *bufferSize = 0;
831ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        return err;
832ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    }
833ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
834054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *minUndequeuedBuffers = 0;
835258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    err = mNativeWindow->query(
836258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
837054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (int *)minUndequeuedBuffers);
838258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
839258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    if (err != 0) {
84029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
841258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                strerror(-err), -err);
842258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        return err;
843258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
844258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
845e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // FIXME: assume that surface is controlled by app (native window
846e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // returns the number for the case when surface is not controlled by app)
8471faa41704e0b976e546321effcb09a85767d51baLajos Molnar    // FIXME2: This means that minUndeqeueudBufs can be 1 larger than reported
8481faa41704e0b976e546321effcb09a85767d51baLajos Molnar    // For now, try to allocate 1 more buffer, but don't fail if unsuccessful
849e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar
850e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // Use conservative allocation while also trying to reduce starvation
851e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //
852e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // 1. allocate at least nBufferCountMin + minUndequeuedBuffers - that is the
853e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //    minimum needed for the consumer to be able to work
854e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // 2. try to allocate two (2) additional buffers to reduce starvation from
855e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //    the consumer
8561faa41704e0b976e546321effcb09a85767d51baLajos Molnar    //    plus an extra buffer to account for incorrect minUndequeuedBufs
8571faa41704e0b976e546321effcb09a85767d51baLajos Molnar    for (OMX_U32 extraBuffers = 2 + 1; /* condition inside loop */; extraBuffers--) {
858e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        OMX_U32 newBufferCount =
859e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            def.nBufferCountMin + *minUndequeuedBuffers + extraBuffers;
860258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        def.nBufferCountActual = newBufferCount;
861258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        err = mOMX->setParameter(
862258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
863258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
864e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        if (err == OK) {
865e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            *minUndequeuedBuffers += extraBuffers;
866e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            break;
867e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        }
868e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar
869609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGW("[%s] setting nBufferCountActual to %u failed: %d",
870e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar                mComponentName.c_str(), newBufferCount, err);
871e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        /* exit condition */
872e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        if (extraBuffers == 0) {
873258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            return err;
874258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        }
875258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
876258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffer_count(
878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(), def.nBufferCountActual);
879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
88129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                -err);
883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
886054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferCount = def.nBufferCountActual;
887054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferSize =  def.nBufferSize;
888054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
889054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
890054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
891054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputBuffersFromNativeWindow() {
892054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
893054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
894054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
895054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
896054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
897e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    mNumUndequeuedBuffers = minUndequeuedBuffers;
898054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
8993298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia    if (!mStoreMetaDataInOutputBuffers) {
9003298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia        static_cast<Surface*>(mNativeWindow.get())
9013298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia                ->getIGraphicBufferProducer()->allowAllocation(true);
9023298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia    }
9033298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia
904609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Allocating %u buffers from a native window of size %u on "
905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         "output port",
906054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount, bufferSize);
907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Dequeue buffers and send them to OMX
909054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
9108ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev        ANativeWindowBuffer *buf;
9111e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
91329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
91874006804065941841883c4b46ee785070164023fJamie Gennis        BufferInfo info;
91974006804065941841883c4b46ee785070164023fJamie Gennis        info.mStatus = BufferInfo::OWNED_BY_US;
920054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(NULL /* data */, bufferSize /* capacity */);
92174006804065941841883c4b46ee785070164023fJamie Gennis        info.mGraphicBuffer = graphicBuffer;
92274006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].push(info);
92374006804065941841883c4b46ee785070164023fJamie Gennis
924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferId;
925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &bufferId);
927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
928609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGE("registering GraphicBuffer %u with OMX IL component failed: "
92974006804065941841883c4b46ee785070164023fJamie Gennis                 "%d", i, err);
930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
93374006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
93474006804065941841883c4b46ee785070164023fJamie Gennis
935609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGV("[%s] Registered graphic buffer with ID %u (pointer = %p)",
936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mComponentName.c_str(),
937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             bufferId, graphicBuffer.get());
938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelStart;
941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelEnd;
942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // If an error occurred while dequeuing we need to cancel any buffers
945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // that were dequeued.
946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelStart = 0;
94774006804065941841883c4b46ee785070164023fJamie Gennis        cancelEnd = mBuffers[kPortIndexOutput].size();
948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
949054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // Return the required minimum undequeued buffers to the native window.
950054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelStart = bufferCount - minUndequeuedBuffers;
951054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelEnd = bufferCount;
952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
9563fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        status_t error = cancelBufferToNativeWindow(info);
9573fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        if (err == 0) {
9583fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia            err = error;
9593fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        }
960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9623298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia    if (!mStoreMetaDataInOutputBuffers) {
9633298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia        static_cast<Surface*>(mNativeWindow.get())
9643298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia                ->getIGraphicBufferProducer()->allowAllocation(false);
9653298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia    }
9663298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia
967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
970054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputMetaDataBuffers() {
971054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
972054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
973054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
974054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
975054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
976e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    mNumUndequeuedBuffers = minUndequeuedBuffers;
977054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
978e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar    ALOGV("[%s] Allocating %u meta buffers on output port",
979e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar         mComponentName.c_str(), bufferCount);
980e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
981e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar    size_t totalSize = bufferCount * 8;
982e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar    mDealer[kPortIndexOutput] = new MemoryDealer(totalSize, "ACodec");
983e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
984e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar    // Dequeue buffers and send them to OMX
985e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
986e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        BufferInfo info;
987e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        info.mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
988e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        info.mGraphicBuffer = NULL;
989e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        info.mDequeuedAt = mDequeueCounter;
990e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
991e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        sp<IMemory> mem = mDealer[kPortIndexOutput]->allocate(
992e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar                sizeof(struct VideoDecoderOutputMetaData));
9935581770ee0dde70e2e9c50533be35e537a5800efChong Zhang        if (mem == NULL || mem->pointer() == NULL) {
994777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return NO_MEMORY;
995777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        }
996e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        info.mData = new ABuffer(mem->pointer(), mem->size());
997e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
998e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        // we use useBuffer for metadata regardless of quirks
999e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        err = mOMX->useBuffer(
1000cc7cc67349b7a3f498882087aa42ffc05a2daf11Lajos Molnar                mNode, kPortIndexOutput, mem, &info.mBufferID, mem->size());
1001e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1002e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        mBuffers[kPortIndexOutput].push(info);
1003e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1004e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        ALOGV("[%s] allocated meta buffer with ID %u (pointer = %p)",
1005e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar             mComponentName.c_str(), info.mBufferID, mem->pointer());
1006e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar    }
1007e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1008011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar    if (mLegacyAdaptiveExperiment) {
1009e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        // preallocate and preregister buffers
1010011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        static_cast<Surface *>(mNativeWindow.get())
1011011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                ->getIGraphicBufferProducer()->allowAllocation(true);
1012011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
1013011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        ALOGV("[%s] Allocating %u buffers from a native window of size %u on "
1014011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar             "output port",
1015011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar             mComponentName.c_str(), bufferCount, bufferSize);
1016011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
1017011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        // Dequeue buffers then cancel them all
1018011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        for (OMX_U32 i = 0; i < bufferCount; i++) {
1019e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar            BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
1020e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1021011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            ANativeWindowBuffer *buf;
1022011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
1023011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            if (err != 0) {
1024011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
1025011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                break;
1026011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            }
1027011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
1028011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
1029e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar            mOMX->updateGraphicBufferInMeta(
1030e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar                    mNode, kPortIndexOutput, graphicBuffer, info->mBufferID);
1031e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar            info->mStatus = BufferInfo::OWNED_BY_US;
1032e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar            info->mGraphicBuffer = graphicBuffer;
1033011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        }
1034011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
1035011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        for (OMX_U32 i = 0; i < mBuffers[kPortIndexOutput].size(); i++) {
1036011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
1037011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            status_t error = cancelBufferToNativeWindow(info);
1038011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            if (err == OK) {
1039011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                err = error;
1040011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            }
1041011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        }
1042011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
1043011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        static_cast<Surface*>(mNativeWindow.get())
1044011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                ->getIGraphicBufferProducer()->allowAllocation(false);
1045011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar    }
1046011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
1047054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mMetaDataBuffersToSubmit = bufferCount - minUndequeuedBuffers;
1048054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
1049054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
1050054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1051054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::submitOutputMetaDataBuffer() {
1052054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mStoreMetaDataInOutputBuffers);
1053054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mMetaDataBuffersToSubmit == 0)
1054054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return OK;
1055054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1056054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *info = dequeueBufferFromNativeWindow();
10570806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (info == NULL) {
1058054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return ERROR_IO;
10590806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
1060054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1061609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] submitting output meta buffer ID %u for graphic buffer %p",
1062054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          mComponentName.c_str(), info->mBufferID, info->mGraphicBuffer.get());
1063054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1064054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    --mMetaDataBuffersToSubmit;
1065777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    status_t err = mOMX->fillBuffer(mNode, info->mBufferID);
1066777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (err == OK) {
1067777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
1068777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
1069054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1070777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    return err;
1071054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
1072054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
10730806340688c937e7b78c2d89db3809274130df4eLajos Molnar// static
10740806340688c937e7b78c2d89db3809274130df4eLajos Molnarconst char *ACodec::_asString(BufferInfo::Status s) {
10750806340688c937e7b78c2d89db3809274130df4eLajos Molnar    switch (s) {
10760806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_US:            return "OUR";
10770806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_COMPONENT:     return "COMPONENT";
10780806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_UPSTREAM:      return "UPSTREAM";
10790806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_DOWNSTREAM:    return "DOWNSTREAM";
10800806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_NATIVE_WINDOW: return "SURFACE";
10810806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::UNRECOGNIZED:           return "UNRECOGNIZED";
10820806340688c937e7b78c2d89db3809274130df4eLajos Molnar        default:                                 return "?";
10830806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
10840806340688c937e7b78c2d89db3809274130df4eLajos Molnar}
10850806340688c937e7b78c2d89db3809274130df4eLajos Molnar
10860806340688c937e7b78c2d89db3809274130df4eLajos Molnarvoid ACodec::dumpBuffers(OMX_U32 portIndex) {
10870806340688c937e7b78c2d89db3809274130df4eLajos Molnar    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
10880806340688c937e7b78c2d89db3809274130df4eLajos Molnar    ALOGI("[%s] %s port has %zu buffers:", mComponentName.c_str(),
10890806340688c937e7b78c2d89db3809274130df4eLajos Molnar            portIndex == kPortIndexInput ? "input" : "output", mBuffers[portIndex].size());
10900806340688c937e7b78c2d89db3809274130df4eLajos Molnar    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
10910806340688c937e7b78c2d89db3809274130df4eLajos Molnar        const BufferInfo &info = mBuffers[portIndex][i];
10920806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGI("  slot %2zu: #%8u %p/%p %s(%d) dequeued:%u",
10930806340688c937e7b78c2d89db3809274130df4eLajos Molnar                i, info.mBufferID, info.mGraphicBuffer.get(),
10940806340688c937e7b78c2d89db3809274130df4eLajos Molnar                info.mGraphicBuffer == NULL ? NULL : info.mGraphicBuffer->getNativeBuffer(),
10950806340688c937e7b78c2d89db3809274130df4eLajos Molnar                _asString(info.mStatus), info.mStatus, info.mDequeuedAt);
10960806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
10970806340688c937e7b78c2d89db3809274130df4eLajos Molnar}
10980806340688c937e7b78c2d89db3809274130df4eLajos Molnar
1099f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
1100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
1101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1102609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Calling cancelBuffer on buffer %u",
1103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mComponentName.c_str(), info->mBufferID);
1104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int err = mNativeWindow->cancelBuffer(
11061e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        mNativeWindow.get(), info->mGraphicBuffer.get(), -1);
1107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
11083fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia    ALOGW_IF(err != 0, "[%s] can not return buffer %u to native window",
11093fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia            mComponentName.c_str(), info->mBufferID);
11100806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // change ownership even if cancelBuffer fails
1111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
1112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
11133fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia    return err;
1114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1116f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
11178ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev    ANativeWindowBuffer *buf;
1118054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mNativeWindow.get() != NULL);
1119ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
1120ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    if (mTunneled) {
1121ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        ALOGW("dequeueBufferFromNativeWindow() should not be called in tunnel"
1122ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad              " video playback mode mode!");
1123ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        return NULL;
1124ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    }
1125ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
1126dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    do {
1127dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        if (native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf) != 0) {
1128dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            ALOGE("dequeueBuffer failed.");
1129dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            return NULL;
1130dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        }
1131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1132dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        bool stale = false;
1133dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
1134dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
1135dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar
1136dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            if (info->mGraphicBuffer != NULL &&
1137dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                info->mGraphicBuffer->handle == buf->handle) {
1138dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // Since consumers can attach buffers to BufferQueues, it is possible
1139dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // that a known yet stale buffer can return from a surface that we
1140dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // once used.  We can simply ignore this as we have already dequeued
1141dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // this buffer properly.  NOTE: this does not eliminate all cases,
1142dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // e.g. it is possible that we have queued the valid buffer to the
1143dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // NW, and a stale copy of the same buffer gets dequeued - which will
1144dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // be treated as the valid buffer by ACodec.
1145dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                if (info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
1146dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                    ALOGI("dequeued stale buffer %p. discarding", buf);
1147dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                    stale = true;
1148dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                    break;
1149dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                }
1150dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                ALOGV("dequeued buffer %p", info->mGraphicBuffer->getNativeBuffer());
1151dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                info->mStatus = BufferInfo::OWNED_BY_US;
1152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1153dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                return info;
1154dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            }
1155dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        }
1156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1157dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // It is also possible to receive a previously unregistered buffer
1158dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // in non-meta mode. These should be treated as stale buffers. The
1159dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // same is possible in meta mode, in which case, it will be treated
1160dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // as a normal buffer, which is not desirable.
1161dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // TODO: fix this.
1162011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        if (!stale && (!mStoreMetaDataInOutputBuffers || mLegacyAdaptiveExperiment)) {
1163dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            ALOGI("dequeued unrecognized (stale) buffer %p. discarding", buf);
1164dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            stale = true;
1165dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        }
1166dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        if (stale) {
1167dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            // TODO: detach stale buffer, but there is no API yet to do it.
1168dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            buf = NULL;
1169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1170dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    } while (buf == NULL);
1171054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1172dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    // get oldest undequeued buffer
1173dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    BufferInfo *oldest = NULL;
1174dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
1175dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        BufferInfo *info =
1176dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            &mBuffers[kPortIndexOutput].editItemAt(i);
1177054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW &&
1178054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (oldest == NULL ||
1179054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             // avoid potential issues from counter rolling over
1180054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mDequeueCounter - info->mDequeuedAt >
1181054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    mDequeueCounter - oldest->mDequeuedAt)) {
1182054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            oldest = info;
1183054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
1184054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1185054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
11860806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // it is impossible dequeue a buffer when there are no buffers with ANW
11870806340688c937e7b78c2d89db3809274130df4eLajos Molnar    CHECK(oldest != NULL);
11880806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // it is impossible to dequeue an unknown buffer in non-meta mode, as the
11890806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // while loop above does not complete
11900806340688c937e7b78c2d89db3809274130df4eLajos Molnar    CHECK(mStoreMetaDataInOutputBuffers);
1191054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
11920806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // discard buffer in LRU info and replace with new buffer
11930806340688c937e7b78c2d89db3809274130df4eLajos Molnar    oldest->mGraphicBuffer = new GraphicBuffer(buf, false);
11940806340688c937e7b78c2d89db3809274130df4eLajos Molnar    oldest->mStatus = BufferInfo::OWNED_BY_US;
1195d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar
11960806340688c937e7b78c2d89db3809274130df4eLajos Molnar    mOMX->updateGraphicBufferInMeta(
11970806340688c937e7b78c2d89db3809274130df4eLajos Molnar            mNode, kPortIndexOutput, oldest->mGraphicBuffer,
11980806340688c937e7b78c2d89db3809274130df4eLajos Molnar            oldest->mBufferID);
1199054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
12000806340688c937e7b78c2d89db3809274130df4eLajos Molnar    VideoDecoderOutputMetaData *metaData =
12010806340688c937e7b78c2d89db3809274130df4eLajos Molnar        reinterpret_cast<VideoDecoderOutputMetaData *>(
12020806340688c937e7b78c2d89db3809274130df4eLajos Molnar                oldest->mData->base());
12030806340688c937e7b78c2d89db3809274130df4eLajos Molnar    CHECK_EQ(metaData->eType, kMetadataBufferTypeGrallocSource);
1204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
12050806340688c937e7b78c2d89db3809274130df4eLajos Molnar    ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
12060806340688c937e7b78c2d89db3809274130df4eLajos Molnar            (unsigned)(oldest - &mBuffers[kPortIndexOutput][0]),
12070806340688c937e7b78c2d89db3809274130df4eLajos Molnar            mDequeueCounter - oldest->mDequeuedAt,
12080806340688c937e7b78c2d89db3809274130df4eLajos Molnar            metaData->pHandle,
12090806340688c937e7b78c2d89db3809274130df4eLajos Molnar            oldest->mGraphicBuffer->handle, oldest->mData->base());
1210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
12110806340688c937e7b78c2d89db3809274130df4eLajos Molnar    return oldest;
1212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1214f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
1215777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    status_t err = OK;
1216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[portIndex].size(); i-- > 0;) {
1217777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        status_t err2 = freeBuffer(portIndex, i);
1218777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        if (err == OK) {
1219777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            err = err2;
1220777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        }
1221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
12230806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // clear mDealer even on an error
1224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDealer[portIndex].clear();
1225777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    return err;
1226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1228349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huberstatus_t ACodec::freeOutputBuffersNotOwnedByComponent() {
1229777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    status_t err = OK;
1230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
1231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
1232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
1233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
12342ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // At this time some buffers may still be with the component
12352ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // or being drained.
12362ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT &&
12372ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar            info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) {
1238777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            status_t err2 = freeBuffer(kPortIndexOutput, i);
1239777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            if (err == OK) {
1240777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                err = err2;
1241777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            }
1242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1245777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    return err;
1246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1248f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
1249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
12500806340688c937e7b78c2d89db3809274130df4eLajos Molnar    status_t err = OK;
1251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
12520806340688c937e7b78c2d89db3809274130df4eLajos Molnar    switch (info->mStatus) {
12530806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_US:
12540806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (portIndex == kPortIndexOutput && mNativeWindow != NULL) {
12550806340688c937e7b78c2d89db3809274130df4eLajos Molnar                (void)cancelBufferToNativeWindow(info);
12560806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
12570806340688c937e7b78c2d89db3809274130df4eLajos Molnar            // fall through
1258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
12590806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_NATIVE_WINDOW:
12600806340688c937e7b78c2d89db3809274130df4eLajos Molnar            err = mOMX->freeBuffer(mNode, portIndex, info->mBufferID);
12610806340688c937e7b78c2d89db3809274130df4eLajos Molnar            break;
12620806340688c937e7b78c2d89db3809274130df4eLajos Molnar
12630806340688c937e7b78c2d89db3809274130df4eLajos Molnar        default:
12640806340688c937e7b78c2d89db3809274130df4eLajos Molnar            ALOGE("trying to free buffer not owned by us or ANW (%d)", info->mStatus);
12650806340688c937e7b78c2d89db3809274130df4eLajos Molnar            err = FAILED_TRANSACTION;
12660806340688c937e7b78c2d89db3809274130df4eLajos Molnar            break;
1267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1269777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    // remove buffer even if mOMX->freeBuffer fails
1270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mBuffers[portIndex].removeAt(i);
1271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1272777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    return err;
1273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1275f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::findBufferByID(
12760806340688c937e7b78c2d89db3809274130df4eLajos Molnar        uint32_t portIndex, IOMX::buffer_id bufferID, ssize_t *index) {
1277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
1278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
1279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mBufferID == bufferID) {
1281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (index != NULL) {
1282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                *index = i;
1283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
1285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1288777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    ALOGE("Could not find buffer with ID %u", bufferID);
1289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
1290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
12925778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setComponentRole(
1293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        bool isEncoder, const char *mime) {
1294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    struct MimeToRole {
1295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime;
1296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *decoderRole;
1297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *encoderRole;
1298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
1299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const MimeToRole kMimeToRole[] = {
1301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG,
1302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.mp3", "audio_encoder.mp3" },
13032944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
13042944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp1", "audio_encoder.mp1" },
13052944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
13062944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp2", "audio_encoder.mp2" },
1307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_NB,
1308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrnb", "audio_encoder.amrnb" },
1309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_WB,
1310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrwb", "audio_encoder.amrwb" },
1311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AAC,
1312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.aac", "audio_encoder.aac" },
1313729de186450f78c099637e1fce743fe531862c52Andreas Huber        { MEDIA_MIMETYPE_AUDIO_VORBIS,
1314729de186450f78c099637e1fce743fe531862c52Andreas Huber            "audio_decoder.vorbis", "audio_encoder.vorbis" },
1315bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian        { MEDIA_MIMETYPE_AUDIO_OPUS,
1316bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian            "audio_decoder.opus", "audio_encoder.opus" },
1317c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_MLAW,
1318c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" },
1319c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_ALAW,
1320c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711alaw", "audio_encoder.g711alaw" },
1321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_AVC,
1322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.avc", "video_encoder.avc" },
13232472b1c0d63454e5d90a982bd6c555de6c3127bdRachad        { MEDIA_MIMETYPE_VIDEO_HEVC,
13242472b1c0d63454e5d90a982bd6c555de6c3127bdRachad            "video_decoder.hevc", "video_encoder.hevc" },
1325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_MPEG4,
1326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.mpeg4", "video_encoder.mpeg4" },
1327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_H263,
1328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.h263", "video_encoder.h263" },
132994705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP8,
133094705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp8", "video_encoder.vp8" },
133194705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP9,
133294705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp9", "video_encoder.vp9" },
1333ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        { MEDIA_MIMETYPE_AUDIO_RAW,
1334ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            "audio_decoder.raw", "audio_encoder.raw" },
13352f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        { MEDIA_MIMETYPE_AUDIO_FLAC,
13362f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            "audio_decoder.flac", "audio_encoder.flac" },
1337ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        { MEDIA_MIMETYPE_AUDIO_MSGSM,
1338ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen            "audio_decoder.gsm", "audio_encoder.gsm" },
1339774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu        { MEDIA_MIMETYPE_VIDEO_MPEG2,
1340774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu            "video_decoder.mpeg2", "video_encoder.mpeg2" },
134197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        { MEDIA_MIMETYPE_AUDIO_AC3,
134297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            "audio_decoder.ac3", "audio_encoder.ac3" },
13438a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        { MEDIA_MIMETYPE_AUDIO_EAC3,
13448a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            "audio_decoder.eac3", "audio_encoder.eac3" },
1345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
1346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const size_t kNumMimeToRole =
1348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
1349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    size_t i;
1351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (i = 0; i < kNumMimeToRole; ++i) {
1352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcasecmp(mime, kMimeToRole[i].mime)) {
1353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (i == kNumMimeToRole) {
13585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_UNSUPPORTED;
1359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    const char *role =
1362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        isEncoder ? kMimeToRole[i].encoderRole
1363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                  : kMimeToRole[i].decoderRole;
1364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (role != NULL) {
1366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_PARAM_COMPONENTROLETYPE roleParams;
1367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        InitOMXParams(&roleParams);
1368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        strncpy((char *)roleParams.cRole,
1370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                role, OMX_MAX_STRINGNAME_SIZE - 1);
1371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
1373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->setParameter(
1375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamStandardComponentRole,
1376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &roleParams, sizeof(roleParams));
1377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
13795ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("[%s] Failed to set standard component role '%s'.",
1380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 mComponentName.c_str(), role);
13815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
1383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
13855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
1387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
13895778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::configureCodec(
1390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime, const sp<AMessage> &msg) {
13915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t encoder;
13925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("encoder", &encoder)) {
13935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        encoder = false;
13945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1396e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    sp<AMessage> inputFormat = new AMessage();
13974e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    sp<AMessage> outputFormat = mNotify->dup(); // will use this for kWhatOutputFormatChanged
1398e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
13995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mIsEncoder = encoder;
1400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14018db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu
14025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setComponentRole(encoder /* isEncoder */, mime);
14035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
14055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
14065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitRate = 0;
14092f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    // FLAC encoder doesn't need a bitrate, other encoders do
14102f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
14112f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            && !msg->findInt32("bitrate", &bitRate)) {
14125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
14135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1415d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    int32_t storeMeta;
1416d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (encoder
1417d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && msg->findInt32("store-metadata-in-buffers", &storeMeta)
1418d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && storeMeta != 0) {
1419d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE);
1420d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1421d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (err != OK) {
1422308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              ALOGE("[%s] storeMetaDataInBuffers (input) failed w/ err %d",
1423308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    mComponentName.c_str(), err);
1424d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1425308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              return err;
1426308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang          }
1427308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang      }
1428d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1429308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t prependSPSPPS = 0;
14303a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    if (encoder
14313a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
14323a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && prependSPSPPS != 0) {
14333a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        OMX_INDEXTYPE index;
14343a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        err = mOMX->getExtensionIndex(
14353a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                mNode,
14363a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                "OMX.google.android.index.prependSPSPPSToIDRFrames",
14373a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                &index);
14383a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
14393a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err == OK) {
14403a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            PrependSPSPPSToIDRFramesParams params;
14413a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            InitOMXParams(&params);
14423a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            params.bEnable = OMX_TRUE;
14433a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
14443a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            err = mOMX->setParameter(
14453a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                    mNode, index, &params, sizeof(params));
14463a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
14473a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
14483a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err != OK) {
14493a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            ALOGE("Encoder could not be configured to emit SPS/PPS before "
14503a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                  "IDR frames. (err %d)", err);
14513a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
14523a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            return err;
14533a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
14543a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    }
14553a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
1456308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // Only enable metadata mode on encoder output if encoder can prepend
1457308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // sps/pps to idr frames, since in metadata mode the bitstream is in an
1458308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // opaque handle, to which we don't have access.
1459308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t video = !strncasecmp(mime, "video/", 6);
14608db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    mIsVideo = video;
1461308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (encoder && video) {
1462308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS
1463308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && msg->findInt32("store-metadata-in-buffers-output", &storeMeta)
1464308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && storeMeta != 0);
1465308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1466308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, enable);
1467308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1468308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        if (err != OK) {
1469308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            ALOGE("[%s] storeMetaDataInBuffers (output) failed w/ err %d",
1470308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                mComponentName.c_str(), err);
1471308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = 0;
1472308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        } else {
1473308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = enable;
1474308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        }
1475a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
1476a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (!msg->findInt64(
1477a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    "repeat-previous-frame-after",
1478a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    &mRepeatFrameDelayUs)) {
1479a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            mRepeatFrameDelayUs = -1ll;
1480a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
148194ee4b708acfa941581160b267afb79192b1d816Chong Zhang
148294ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (!msg->findInt64("max-pts-gap-to-encoder", &mMaxPtsGapUs)) {
14832c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mMaxPtsGapUs = -1ll;
14842c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
14852c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
148637b2b389139ed638831e49708c947863eef631efRonghua Wu        if (!msg->findFloat("max-fps-to-encoder", &mMaxFps)) {
148737b2b389139ed638831e49708c947863eef631efRonghua Wu            mMaxFps = -1;
148837b2b389139ed638831e49708c947863eef631efRonghua Wu        }
148937b2b389139ed638831e49708c947863eef631efRonghua Wu
14902c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (!msg->findInt64("time-lapse", &mTimePerCaptureUs)) {
14912c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mTimePerCaptureUs = -1ll;
149294ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
149372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
149472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (!msg->findInt32(
149572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    "create-input-buffers-suspended",
149672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    (int32_t*)&mCreateInputBuffersSuspended)) {
149772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mCreateInputBuffersSuspended = false;
149872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
1499308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    }
1500308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
15013a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar    // NOTE: we only use native window for video decoders
1502054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    sp<RefBase> obj;
15030d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    bool haveNativeWindow = msg->findObject("native-window", &obj)
15043a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            && obj != NULL && video && !encoder;
1505054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mStoreMetaDataInOutputBuffers = false;
1506011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar    mLegacyAdaptiveExperiment = false;
1507e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if (video && !encoder) {
1508e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        inputFormat->setInt32("adaptive-playback", false);
15091713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang
15101713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        int32_t usageProtected;
15111713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        if (msg->findInt32("protected", &usageProtected) && usageProtected) {
15121713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            if (!haveNativeWindow) {
15131713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang                ALOGE("protected output buffers must be sent to an ANativeWindow");
15141713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang                return PERMISSION_DENIED;
15151713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            }
15161713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            mFlags |= kFlagIsGrallocUsageProtected;
15171713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
15181713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        }
1519e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
15203a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar    if (haveNativeWindow) {
15211de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar        sp<ANativeWindow> nativeWindow =
15221de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar            static_cast<ANativeWindow *>(static_cast<Surface *>(obj.get()));
15235a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
15246597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        // START of temporary support for automatic FRC - THIS WILL BE REMOVED
15256597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        int32_t autoFrc;
15266597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        if (msg->findInt32("auto-frc", &autoFrc)) {
15276597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            bool enabled = autoFrc;
15286597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            OMX_CONFIG_BOOLEANTYPE config;
15296597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            InitOMXParams(&config);
15306597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            config.bEnabled = (OMX_BOOL)enabled;
15316597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            status_t temp = mOMX->setConfig(
15326597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                    mNode, (OMX_INDEXTYPE)OMX_IndexConfigAutoFramerateConversion,
15336597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                    &config, sizeof(config));
15346597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            if (temp == OK) {
15356597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                outputFormat->setInt32("auto-frc", enabled);
15366597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            } else if (enabled) {
15376597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                ALOGI("codec does not support requested auto-frc (err %d)", temp);
15386597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            }
15396597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        }
15406597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        // END of temporary support for automatic FRC
15416597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar
15425a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        int32_t tunneled;
15435a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        if (msg->findInt32("feature-tunneled-playback", &tunneled) &&
15445a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            tunneled != 0) {
15455a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            ALOGI("Configuring TUNNELED video playback.");
1546ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            mTunneled = true;
15475a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
154897827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad            int32_t audioHwSync = 0;
154997827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad            if (!msg->findInt32("audio-hw-sync", &audioHwSync)) {
15505a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGW("No Audio HW Sync provided for video tunnel");
15515a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            }
15525a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            err = configureTunneledVideoPlayback(audioHwSync, nativeWindow);
15535a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (err != OK) {
155497827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad                ALOGE("configureTunneledVideoPlayback(%d,%p) failed!",
15555a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        audioHwSync, nativeWindow.get());
15565a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                return err;
1557fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
1558fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1559d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            int32_t maxWidth = 0, maxHeight = 0;
1560d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            if (msg->findInt32("max-width", &maxWidth) &&
1561d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    msg->findInt32("max-height", &maxHeight)) {
1562d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad
1563d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                err = mOMX->prepareForAdaptivePlayback(
1564d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                        mNode, kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight);
1565d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                if (err != OK) {
1566d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    ALOGW("[%s] prepareForAdaptivePlayback failed w/ err %d",
1567d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                            mComponentName.c_str(), err);
15683a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    // allow failure
15693a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    err = OK;
1570d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                } else {
1571d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("max-width", maxWidth);
1572d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("max-height", maxHeight);
1573d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("adaptive-playback", true);
1574d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                }
1575d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            }
15765a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        } else {
1577ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            ALOGV("Configuring CPU controlled video playback.");
1578ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            mTunneled = false;
1579ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
15803fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // Explicity reset the sideband handle of the window for
15813fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // non-tunneled video in case the window was previously used
15823fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // for a tunneled video playback.
15833fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            err = native_window_set_sideband_stream(nativeWindow.get(), NULL);
15843fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            if (err != OK) {
15853fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad                ALOGE("set_sideband_stream(NULL) failed! (err %d).", err);
15863fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad                return err;
15873fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            }
15883fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad
15895a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            // Always try to enable dynamic output buffers on native surface
15905a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            err = mOMX->storeMetaDataInBuffers(
15915a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    mNode, kPortIndexOutput, OMX_TRUE);
15925a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (err != OK) {
15935a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d",
1594fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        mComponentName.c_str(), err);
1595e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
15965a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // if adaptive playback has been requested, try JB fallback
15975a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // NOTE: THIS FALLBACK MECHANISM WILL BE REMOVED DUE TO ITS
15985a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // LARGE MEMORY REQUIREMENT
15995a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
16005a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // we will not do adaptive playback on software accessed
16015a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // surfaces as they never had to respond to changes in the
16025a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // crop window, and we don't trust that they will be able to.
16035a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                int usageBits = 0;
16045a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                bool canDoAdaptivePlayback;
16055a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
16065a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                if (nativeWindow->query(
16075a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        nativeWindow.get(),
16085a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        NATIVE_WINDOW_CONSUMER_USAGE_BITS,
16095a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        &usageBits) != OK) {
16105a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    canDoAdaptivePlayback = false;
16115a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                } else {
16125a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    canDoAdaptivePlayback =
16135a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        (usageBits &
16145a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                                (GRALLOC_USAGE_SW_READ_MASK |
16155a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                                 GRALLOC_USAGE_SW_WRITE_MASK)) == 0;
16165a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                }
16175a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
16185a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                int32_t maxWidth = 0, maxHeight = 0;
16195a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                if (canDoAdaptivePlayback &&
16205a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        msg->findInt32("max-width", &maxWidth) &&
16215a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        msg->findInt32("max-height", &maxHeight)) {
16225a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    ALOGV("[%s] prepareForAdaptivePlayback(%dx%d)",
16235a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mComponentName.c_str(), maxWidth, maxHeight);
16245a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
16255a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    err = mOMX->prepareForAdaptivePlayback(
16265a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mNode, kPortIndexOutput, OMX_TRUE, maxWidth,
16275a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            maxHeight);
16285a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    ALOGW_IF(err != OK,
16295a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            "[%s] prepareForAdaptivePlayback failed w/ err %d",
16305a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mComponentName.c_str(), err);
16315a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
16325a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    if (err == OK) {
16335a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("max-width", maxWidth);
16345a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("max-height", maxHeight);
16355a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("adaptive-playback", true);
16365a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    }
1637e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
16385a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // allow failure
16395a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                err = OK;
16405a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            } else {
16415a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGV("[%s] storeMetaDataInBuffers succeeded",
16425a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        mComponentName.c_str());
16435a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                mStoreMetaDataInOutputBuffers = true;
1644011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                mLegacyAdaptiveExperiment = ADebug::isExperimentEnabled(
1645011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                        "legacy-adaptive", !msg->contains("no-experiments"));
1646011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
16475a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                inputFormat->setInt32("adaptive-playback", true);
1648fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
16490167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber
16505a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            int32_t push;
16515a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (msg->findInt32("push-blank-buffers-on-shutdown", &push)
16525a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    && push != 0) {
16535a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
16545a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            }
16550167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        }
1656e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang
1657e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        int32_t rotationDegrees;
1658e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        if (msg->findInt32("rotation-degrees", &rotationDegrees)) {
1659e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            mRotationDegrees = rotationDegrees;
1660e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        } else {
1661e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            mRotationDegrees = 0;
1662e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        }
1663054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1664054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1665308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (video) {
16663a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // determine need for software renderer
16673a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        bool usingSwRenderer = false;
16683a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (haveNativeWindow && mComponentName.startsWith("OMX.google.")) {
16693a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            usingSwRenderer = true;
16703a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            haveNativeWindow = false;
16713a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
16723a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
16735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (encoder) {
16745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupVideoEncoder(mime, msg);
16755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
16760d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            err = setupVideoDecoder(mime, msg, haveNativeWindow);
16775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16783a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
16793a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (err != OK) {
16803a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            return err;
16813a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
16823a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
16833a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (haveNativeWindow) {
16841de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar            mNativeWindow = static_cast<Surface *>(obj.get());
16853a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
16863a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
16873a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // initialize native window now to get actual output format
16883a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // TODO: this is needed for some encoders even though they don't use native window
1689777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        err = initNativeWindow();
1690777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        if (err != OK) {
1691777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return err;
1692777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        }
16933a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
16943a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // fallback for devices that do not handle flex-YUV for native buffers
16953a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (haveNativeWindow) {
16963a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            int32_t requestedColorFormat = OMX_COLOR_FormatUnused;
16973a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            if (msg->findInt32("color-format", &requestedColorFormat) &&
16983a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    requestedColorFormat == OMX_COLOR_FormatYUV420Flexible) {
1699777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                status_t err = getPortFormat(kPortIndexOutput, outputFormat);
1700777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (err != OK) {
1701777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return err;
1702777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
17033a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                int32_t colorFormat = OMX_COLOR_FormatUnused;
17043a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                OMX_U32 flexibleEquivalent = OMX_COLOR_FormatUnused;
1705777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (!outputFormat->findInt32("color-format", &colorFormat)) {
1706777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGE("ouptut port did not have a color format (wrong domain?)");
1707777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return BAD_VALUE;
1708777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
17093a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                ALOGD("[%s] Requested output format %#x and got %#x.",
17103a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        mComponentName.c_str(), requestedColorFormat, colorFormat);
17113a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                if (!isFlexibleColorFormat(
17123a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                                mOMX, mNode, colorFormat, haveNativeWindow, &flexibleEquivalent)
17133a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        || flexibleEquivalent != (OMX_U32)requestedColorFormat) {
17143a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    // device did not handle flex-YUV request for native window, fall back
17153a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    // to SW renderer
17163a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    ALOGI("[%s] Falling back to software renderer", mComponentName.c_str());
17173a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    mNativeWindow.clear();
17183a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    haveNativeWindow = false;
17193a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    usingSwRenderer = true;
17203a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    if (mStoreMetaDataInOutputBuffers) {
17213a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, OMX_FALSE);
17223a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        mStoreMetaDataInOutputBuffers = false;
17233a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        // TODO: implement adaptive-playback support for bytebuffer mode.
17243a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        // This is done by SW codecs, but most HW codecs don't support it.
17253a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        inputFormat->setInt32("adaptive-playback", false);
17263a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
17273a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    if (err == OK) {
17283a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        err = mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
17293a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
17303a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    if (mFlags & kFlagIsGrallocUsageProtected) {
17313a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        // fallback is not supported for protected playback
17323a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        err = PERMISSION_DENIED;
17333a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    } else if (err == OK) {
17343a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        err = setupVideoDecoder(mime, msg, false);
17353a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
17363a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                }
17373a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            }
17383a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
17393a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
17403a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (usingSwRenderer) {
17413a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            outputFormat->setInt32("using-sw-renderer", 1);
17423a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
174342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
174442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        int32_t numChannels, sampleRate;
174542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        if (!msg->findInt32("channel-count", &numChannels)
174642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
174742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // Since we did not always check for these, leave them optional
174842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // and have the decoder figure it all out.
174942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = OK;
175042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        } else {
175142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = setupRawAudioFormat(
175242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    encoder ? kPortIndexInput : kPortIndexOutput,
175342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    sampleRate,
175442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    numChannels);
175542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        }
1756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
1757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t numChannels, sampleRate;
17585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)
17595778822d86b0337407514b9372562b86edfa91cdAndreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
17605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
17615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
1762aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            int32_t isADTS, aacProfile;
1763b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            int32_t sbrMode;
17648045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            int32_t maxOutputChannelCount;
17652965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            int32_t pcmLimiterEnable;
17668045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            drcParams_t drc;
1767ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            if (!msg->findInt32("is-adts", &isADTS)) {
1768ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                isADTS = 0;
1769ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
1770aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (!msg->findInt32("aac-profile", &aacProfile)) {
1771aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                aacProfile = OMX_AUDIO_AACObjectNull;
1772aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
1773b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            if (!msg->findInt32("aac-sbr-mode", &sbrMode)) {
1774b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                sbrMode = -1;
1775b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            }
1776ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
17778045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-max-output-channel_count", &maxOutputChannelCount)) {
17788045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                maxOutputChannelCount = -1;
17798045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
17802965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            if (!msg->findInt32("aac-pcm-limiter-enable", &pcmLimiterEnable)) {
17812965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                // value is unknown
17822965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                pcmLimiterEnable = -1;
17832965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            }
17848045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-encoded-target-level", &drc.encodedTargetLevel)) {
17858045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
17868045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.encodedTargetLevel = -1;
17878045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
17888045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-cut-level", &drc.drcCut)) {
17898045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
17908045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.drcCut = -1;
17918045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
17928045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-boost-level", &drc.drcBoost)) {
17938045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
17948045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.drcBoost = -1;
17958045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
17968045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-heavy-compression", &drc.heavyCompression)) {
17978045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
17988045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.heavyCompression = -1;
17998045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
18008045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-target-ref-level", &drc.targetRefLevel)) {
18018045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
18028045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.targetRefLevel = -1;
18038045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
18048045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi
1805ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            err = setupAACCodec(
18064471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    encoder, numChannels, sampleRate, bitRate, aacProfile,
18072965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                    isADTS != 0, sbrMode, maxOutputChannelCount, drc,
18082965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                    pcmLimiterEnable);
18095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
1810729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
18115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
1812729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
18135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
1814729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
1815729de186450f78c099637e1fce743fe531862c52Andreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
1816729de186450f78c099637e1fce743fe531862c52Andreas Huber        // These are PCM-like formats with a fixed sample rate but
1817729de186450f78c099637e1fce743fe531862c52Andreas Huber        // a variable number of channels.
1818729de186450f78c099637e1fce743fe531862c52Andreas Huber
1819729de186450f78c099637e1fce743fe531862c52Andreas Huber        int32_t numChannels;
18205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)) {
18215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
18225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
182317c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            int32_t sampleRate;
182417c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            if (!msg->findInt32("sample-rate", &sampleRate)) {
182517c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen                sampleRate = 8000;
182617c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            }
182717c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            err = setupG711Codec(encoder, sampleRate, numChannels);
18285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18292f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
1830ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        int32_t numChannels = 0, sampleRate = 0, compressionLevel = -1;
18312f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (encoder &&
18322f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                (!msg->findInt32("channel-count", &numChannels)
18332f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                        || !msg->findInt32("sample-rate", &sampleRate))) {
18342f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("missing channel count or sample rate for FLAC encoder");
18352f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            err = INVALID_OPERATION;
18362f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        } else {
18372f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            if (encoder) {
1838516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                if (!msg->findInt32(
1839cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                            "complexity", &compressionLevel) &&
1840cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                    !msg->findInt32(
1841516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                            "flac-compression-level", &compressionLevel)) {
1842cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                    compressionLevel = 5; // default FLAC compression level
18432f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel < 0) {
1844516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1845516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 0",
1846516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
18472f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 0;
18482f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel > 8) {
1849516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1850516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 8",
1851516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
18522f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 8;
18532f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                }
18542f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            }
1855516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            err = setupFlacCodec(
1856516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    encoder, numChannels, sampleRate, compressionLevel);
18572f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
1858ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
1859ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        int32_t numChannels, sampleRate;
1860ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        if (encoder
1861ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("channel-count", &numChannels)
1862ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
1863ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = INVALID_OPERATION;
1864ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        } else {
1865ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
1866ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        }
186797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AC3)) {
186897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t numChannels;
186997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t sampleRate;
187097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        if (!msg->findInt32("channel-count", &numChannels)
187197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                || !msg->findInt32("sample-rate", &sampleRate)) {
187297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = INVALID_OPERATION;
187397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        } else {
187497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = setupAC3Codec(encoder, numChannels, sampleRate);
187597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        }
18768a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_EAC3)) {
18778a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        int32_t numChannels;
18788a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        int32_t sampleRate;
18798a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        if (!msg->findInt32("channel-count", &numChannels)
18808a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                || !msg->findInt32("sample-rate", &sampleRate)) {
18818a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            err = INVALID_OPERATION;
18828a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        } else {
18838a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            err = setupEAC3Codec(encoder, numChannels, sampleRate);
18848a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        }
18855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1886729de186450f78c099637e1fce743fe531862c52Andreas Huber
18874471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    if (err != OK) {
18884471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber        return err;
18894471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    }
18904471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber
18918b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
18928b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderDelay = 0;
18938b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
18949806555d3930be43e11106281dee354820ac1c88Andreas Huber
18958b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
18968b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderPadding = 0;
18978b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
18988b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen
18999806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (msg->findInt32("channel-mask", &mChannelMask)) {
19009806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = true;
19019806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else {
19029806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = false;
19039806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
19049806555d3930be43e11106281dee354820ac1c88Andreas Huber
1905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t maxInputSize;
1906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (msg->findInt32("max-input-size", &maxInputSize)) {
19075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
1908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
19095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
1910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
19115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19128b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    int32_t priority;
19138b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    if (msg->findInt32("priority", &priority)) {
19148b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu        err = setPriority(priority);
19158b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    }
19168b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu
1917ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    int32_t rateInt = -1;
1918ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    float rateFloat = -1;
1919ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (!msg->findFloat("operating-rate", &rateFloat)) {
1920ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        msg->findInt32("operating-rate", &rateInt);
1921ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        rateFloat = (float)rateInt;  // 16MHz (FLINTMAX) is OK for upper bound.
1922ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
1923ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (rateFloat > 0) {
1924ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        err = setOperatingRate(rateFloat, video);
1925ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
1926ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu
19274e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    mBaseOutputFormat = outputFormat;
19284e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar
1929777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    err = getPortFormat(kPortIndexInput, inputFormat);
1930777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (err == OK) {
1931777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        err = getPortFormat(kPortIndexOutput, outputFormat);
1932777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        if (err == OK) {
1933777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            mInputFormat = inputFormat;
1934777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            mOutputFormat = outputFormat;
1935777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        }
1936777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
19375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
1938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
19408b806ea894ca098366629458bfdd1df4866afcdfRonghua Wustatus_t ACodec::setPriority(int32_t priority) {
19418b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    if (priority < 0) {
19428b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu        return BAD_VALUE;
19438b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    }
19448b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    OMX_PARAM_U32TYPE config;
19458b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    InitOMXParams(&config);
19468b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    config.nU32 = (OMX_U32)priority;
19478b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    status_t temp = mOMX->setConfig(
19488b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu            mNode, (OMX_INDEXTYPE)OMX_IndexConfigPriority,
19498b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu            &config, sizeof(config));
19508b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    if (temp != OK) {
19518b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu        ALOGI("codec does not support config priority (err %d)", temp);
19528b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    }
19538b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    return OK;
19548b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu}
19558b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu
1956ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wustatus_t ACodec::setOperatingRate(float rateFloat, bool isVideo) {
1957ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (rateFloat < 0) {
1958ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        return BAD_VALUE;
1959ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
1960ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    OMX_U32 rate;
1961ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (isVideo) {
1962ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        if (rateFloat > 65535) {
1963ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            return BAD_VALUE;
1964ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        }
1965ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        rate = (OMX_U32)(rateFloat * 65536.0f + 0.5f);
1966ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    } else {
1967ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        if (rateFloat > UINT_MAX) {
1968ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            return BAD_VALUE;
1969ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        }
1970ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        rate = (OMX_U32)(rateFloat);
1971ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
1972ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    OMX_PARAM_U32TYPE config;
1973ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    InitOMXParams(&config);
1974ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    config.nU32 = rate;
1975ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    status_t err = mOMX->setConfig(
1976ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            mNode, (OMX_INDEXTYPE)OMX_IndexConfigOperatingRate,
1977ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            &config, sizeof(config));
1978ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (err != OK) {
1979ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        ALOGI("codec does not support config operating rate (err %d)", err);
1980ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
1981ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    return OK;
1982ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu}
1983ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu
1984f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
1985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
1987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
1988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (def.nBufferSize >= size) {
1997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
1998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nBufferSize = size;
2001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
2003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->getParameter(
2010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2016777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (def.nBufferSize < size) {
2017777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("failed to set min buffer size to %zu (is still %u)", size, def.nBufferSize);
2018777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return FAILED_TRANSACTION;
2019777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
2020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
20245778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::selectAudioPortFormat(
20255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
20265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_AUDIO_PARAM_PORTFORMATTYPE format;
20275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&format);
20285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    format.nPortIndex = portIndex;
20305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (OMX_U32 index = 0;; ++index) {
20315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        format.nIndex = index;
20325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
20345778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioPortFormat,
20355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &format, sizeof(format));
20365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
20385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
20395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (format.eEncoding == desiredFormat) {
20425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
20435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
20475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format));
20485778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
20495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20505778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAACCodec(
2051aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        bool encoder, int32_t numChannels, int32_t sampleRate,
20528045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        int32_t bitRate, int32_t aacProfile, bool isADTS, int32_t sbrMode,
20532965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang        int32_t maxOutputChannelCount, const drcParams_t& drc,
20542965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang        int32_t pcmLimiterEnable) {
2055ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (encoder && isADTS) {
2056ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return -EINVAL;
2057ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
2058ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
20595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setupRawAudioFormat(
20605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
20615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sampleRate,
20625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            numChannels);
20635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (encoder) {
20695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
20705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
20725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
20735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
20765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
20775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = kPortIndexOutput;
20785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
20805778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
20815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
20835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
20845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.bFlagErrorConcealment = OMX_TRUE;
20875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
20885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
20905778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
20915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
20935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
20945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
20975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&profile);
20985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nPortIndex = kPortIndexOutput;
20995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
21015778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
21025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
21045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
21055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nChannels = numChannels;
21085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eChannelMode =
21105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (numChannels == 1)
21115778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
21125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nSampleRate = sampleRate;
21145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nBitRate = bitRate;
21155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAudioBandWidth = 0;
21165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nFrameLength = 0;
21175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACtools = OMX_AUDIO_AACToolAll;
21185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACERtools = OMX_AUDIO_AACERNone;
2119aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
21205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
2121b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        switch (sbrMode) {
2122b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 0:
2123b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // disable sbr
2124b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
2125b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
2126b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2127b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 1:
2128b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable single-rate sbr
2129b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
2130b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
2131b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2132b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 2:
2133b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable dual-rate sbr
2134b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
2135b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
2136b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2137b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case -1:
2138b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable both modes -> the codec will decide which mode should be used
2139b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
2140b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
2141b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2142b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        default:
2143b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // unsupported sbr mode
2144b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            return BAD_VALUE;
2145b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        }
2146b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi
21475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
21495778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
21505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
21525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
21535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_AUDIO_PARAM_AACPROFILETYPE profile;
2159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&profile);
2160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nPortIndex = kPortIndexInput;
2161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
21625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
2163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
2164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nChannels = numChannels;
2170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nSampleRate = sampleRate;
2171ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2172ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    profile.eAACStreamFormat =
2173ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        isADTS
2174ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            ? OMX_AUDIO_AACStreamFormatMP4ADTS
2175ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            : OMX_AUDIO_AACStreamFormatMP4FF;
2176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
21778045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    OMX_AUDIO_PARAM_ANDROID_AACPRESENTATIONTYPE presentation;
21788045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nMaxOutputChannels = maxOutputChannelCount;
21798045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nDrcCut = drc.drcCut;
21808045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nDrcBoost = drc.drcBoost;
21818045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nHeavyCompression = drc.heavyCompression;
21828045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nTargetReferenceLevel = drc.targetRefLevel;
21838045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nEncodedTargetLevel = drc.encodedTargetLevel;
21842965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang    presentation.nPCMLimiterEnable = pcmLimiterEnable;
21858045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi
21868045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    status_t res = mOMX->setParameter(mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
21878045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    if (res == OK) {
21888045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        // optional parameters, will not cause configuration failure
21898045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        mOMX->setParameter(mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAacPresentation,
21908045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                &presentation, sizeof(presentation));
21918045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    } else {
21928045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        ALOGW("did not set AudioAndroidAacPresentation due to error %d when setting AudioAac", res);
21938045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    }
21948045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    return res;
21955778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
2196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
219797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryustatus_t ACodec::setupAC3Codec(
219897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        bool encoder, int32_t numChannels, int32_t sampleRate) {
219997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    status_t err = setupRawAudioFormat(
220097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
220197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
220297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
220397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
220497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
220597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
220697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (encoder) {
220797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        ALOGW("AC3 encoding is not supported.");
220897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return INVALID_OPERATION;
220997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
221097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
221197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    OMX_AUDIO_PARAM_ANDROID_AC3TYPE def;
221297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    InitOMXParams(&def);
221397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nPortIndex = kPortIndexInput;
221497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
221597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    err = mOMX->getParameter(
221697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
221797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
221897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
221997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
222097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
222197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
222297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
222397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
222497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
222597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nChannels = numChannels;
222697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nSampleRate = sampleRate;
222797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
222897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    return mOMX->setParameter(
222997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
223097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
223197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
223297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
223397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu}
223497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
22358a4728966dc9c78e21c3c93a927707e93c05e5e0Rachadstatus_t ACodec::setupEAC3Codec(
22368a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        bool encoder, int32_t numChannels, int32_t sampleRate) {
22378a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    status_t err = setupRawAudioFormat(
22388a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
22398a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
22408a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (err != OK) {
22418a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return err;
22428a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
22438a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
22448a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (encoder) {
22458a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        ALOGW("EAC3 encoding is not supported.");
22468a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return INVALID_OPERATION;
22478a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
22488a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
22498a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    OMX_AUDIO_PARAM_ANDROID_EAC3TYPE def;
22508a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    InitOMXParams(&def);
22518a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nPortIndex = kPortIndexInput;
22528a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
22538a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    err = mOMX->getParameter(
22548a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            mNode,
22558a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
22568a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            &def,
22578a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            sizeof(def));
22588a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
22598a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (err != OK) {
22608a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return err;
22618a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
22628a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
22638a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nChannels = numChannels;
22648a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nSampleRate = sampleRate;
22658a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
22668a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    return mOMX->setParameter(
22678a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            mNode,
22688a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
22698a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            &def,
22708a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            sizeof(def));
22718a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad}
22728a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
22735778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
22745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        bool isAMRWB, int32_t bps) {
22755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (isAMRWB) {
22765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 6600) {
22775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB0;
22785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 8850) {
22795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB1;
22805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 12650) {
22815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB2;
22825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 14250) {
22835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB3;
22845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 15850) {
22855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB4;
22865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 18250) {
22875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB5;
22885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 19850) {
22895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB6;
22905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 23050) {
22915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB7;
22925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 23850 bps
22955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeWB8;
22965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {  // AMRNB
22975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 4750) {
22985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB0;
22995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5150) {
23005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB1;
23015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5900) {
23025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB2;
23035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 6700) {
23045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB3;
23055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7400) {
23065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB4;
23075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7950) {
23085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB5;
23095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 10200) {
23105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB6;
23115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 12200 bps
23145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeNB7;
23155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
23185778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
2319729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_AMRTYPE def;
2320729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
23215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
2322729de186450f78c099637e1fce743fe531862c52Andreas Huber
2323729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err =
2324729de186450f78c099637e1fce743fe531862c52Andreas Huber        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
2325729de186450f78c099637e1fce743fe531862c52Andreas Huber
2326729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2327729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2328729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2329729de186450f78c099637e1fce743fe531862c52Andreas Huber
2330729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
23315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
23325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
23345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
2335729de186450f78c099637e1fce743fe531862c52Andreas Huber
23365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
23375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
23385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2339729de186450f78c099637e1fce743fe531862c52Andreas Huber
23405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupRawAudioFormat(
23415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
23425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            isWAMR ? 16000 : 8000 /* sampleRate */,
23435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            1 /* numChannels */);
2344729de186450f78c099637e1fce743fe531862c52Andreas Huber}
2345729de186450f78c099637e1fce743fe531862c52Andreas Huber
234617c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissenstatus_t ACodec::setupG711Codec(bool encoder, int32_t sampleRate, int32_t numChannels) {
2347777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (encoder) {
2348777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return INVALID_OPERATION;
2349777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
23505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2351729de186450f78c099637e1fce743fe531862c52Andreas Huber    return setupRawAudioFormat(
235217c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            kPortIndexInput, sampleRate, numChannels);
2353729de186450f78c099637e1fce743fe531862c52Andreas Huber}
2354729de186450f78c099637e1fce743fe531862c52Andreas Huber
23552f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivistatus_t ACodec::setupFlacCodec(
23562f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
23572f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
23582f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder) {
23592f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        OMX_AUDIO_PARAM_FLACTYPE def;
23602f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        InitOMXParams(&def);
23612f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nPortIndex = kPortIndexOutput;
23622f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
23632f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        // configure compression level
23642f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        status_t err = mOMX->getParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
23652f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
23662f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
23672f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
23682f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
23692f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nCompressionLevel = compressionLevel;
23702f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        err = mOMX->setParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
23712f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
23722f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
23732f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
23742f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
23752f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
23762f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
23772f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    return setupRawAudioFormat(
23782f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            encoder ? kPortIndexInput : kPortIndexOutput,
23792f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            sampleRate,
23802f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            numChannels);
23812f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi}
23822f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
2383729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t ACodec::setupRawAudioFormat(
2384729de186450f78c099637e1fce743fe531862c52Andreas Huber        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
2385729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
2386729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
2387729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.nPortIndex = portIndex;
2388729de186450f78c099637e1fce743fe531862c52Andreas Huber
2389729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err = mOMX->getParameter(
2390729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2391729de186450f78c099637e1fce743fe531862c52Andreas Huber
2392729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2393729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2394729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2395729de186450f78c099637e1fce743fe531862c52Andreas Huber
2396729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
2397729de186450f78c099637e1fce743fe531862c52Andreas Huber
2398729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->setParameter(
2399729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2400729de186450f78c099637e1fce743fe531862c52Andreas Huber
2401729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2402729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2403729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2404729de186450f78c099637e1fce743fe531862c52Andreas Huber
2405729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
2406729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&pcmParams);
2407729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nPortIndex = portIndex;
2408729de186450f78c099637e1fce743fe531862c52Andreas Huber
2409729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->getParameter(
2410729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
2411729de186450f78c099637e1fce743fe531862c52Andreas Huber
2412729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2413729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2414729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2415729de186450f78c099637e1fce743fe531862c52Andreas Huber
2416729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nChannels = numChannels;
2417729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.eNumData = OMX_NumericalDataSigned;
2418729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.bInterleaved = OMX_TRUE;
2419729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nBitPerSample = 16;
2420729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nSamplingRate = sampleRate;
2421729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
2422729de186450f78c099637e1fce743fe531862c52Andreas Huber
2423c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber    if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
2424c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber        return OMX_ErrorNone;
2425729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2426729de186450f78c099637e1fce743fe531862c52Andreas Huber
2427729de186450f78c099637e1fce743fe531862c52Andreas Huber    return mOMX->setParameter(
2428729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
2429729de186450f78c099637e1fce743fe531862c52Andreas Huber}
2430729de186450f78c099637e1fce743fe531862c52Andreas Huber
24315a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachadstatus_t ACodec::configureTunneledVideoPlayback(
243297827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad        int32_t audioHwSync, const sp<ANativeWindow> &nativeWindow) {
24335a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    native_handle_t* sidebandHandle;
24345a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
24355a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    status_t err = mOMX->configureVideoTunnelMode(
24365a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            mNode, kPortIndexOutput, OMX_TRUE, audioHwSync, &sidebandHandle);
24375a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    if (err != OK) {
24385a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        ALOGE("configureVideoTunnelMode failed! (err %d).", err);
24395a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        return err;
24405a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    }
24415a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
24425a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    err = native_window_set_sideband_stream(nativeWindow.get(), sidebandHandle);
24435a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    if (err != OK) {
24445a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        ALOGE("native_window_set_sideband_stream(%p) failed! (err %d).",
24455a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                sidebandHandle, err);
24465a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        return err;
24475a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    }
24485a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
24495a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    return OK;
24505a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad}
24515a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
2452f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoPortFormatType(
2453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
2454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_VIDEO_CODINGTYPE compressionFormat,
24550d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        OMX_COLOR_FORMATTYPE colorFormat,
24560d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        bool usingNativeBuffers) {
2457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
2458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
2459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = portIndex;
2460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
2461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool found = false;
2462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 index = 0;
2464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (;;) {
2465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        format.nIndex = index;
2466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->getParameter(
2467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamVideoPortFormat,
2468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &format, sizeof(format));
2469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
2471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return err;
2472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2474229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        // substitute back flexible color format to codec supported format
2475229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        OMX_U32 flexibleEquivalent;
24760d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (compressionFormat == OMX_VIDEO_CodingUnused
24770d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && isFlexibleColorFormat(
24780d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        mOMX, mNode, format.eColorFormat, usingNativeBuffers, &flexibleEquivalent)
24790d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && colorFormat == flexibleEquivalent) {
2480229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            ALOGI("[%s] using color format %#x in place of %#x",
2481229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                    mComponentName.c_str(), format.eColorFormat, colorFormat);
2482229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            colorFormat = format.eColorFormat;
2483229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
2484229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
2485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The following assertion is violated by TI's video decoder.
2486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // CHECK_EQ(format.nIndex, index);
2487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
2489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexInput
2490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && colorFormat == format.eColorFormat) {
2491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eCompressionFormat does not seem right.
2492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
2493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
2494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexOutput
2496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && compressionFormat == format.eCompressionFormat) {
2497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eColorFormat does not seem right.
2498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
2499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
2500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (format.eCompressionFormat == compressionFormat
2504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && format.eColorFormat == colorFormat) {
2505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            found = true;
2506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ++index;
2510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!found) {
2513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return UNKNOWN_ERROR;
2514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->setParameter(
2517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
2518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
2519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
2521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
25230d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// Set optimal output format. OMX component lists output formats in the order
25240d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// of preference, but this got more complicated since the introduction of flexible
25250d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// YUV formats. We support a legacy behavior for applications that do not use
25260d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// surface output, do not specify an output format, but expect a "usable" standard
25270d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// OMX format. SW readable and standard formats must be flex-YUV.
25280d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar//
25290d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// Suggested preference order:
25300d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal format for texture rendering (mediaplayer behavior)
25310d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal SW readable & texture renderable format (flex-YUV support)
25320d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal SW readable non-renderable format (flex-YUV bytebuffer support)
25330d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - legacy "usable" standard formats
25340d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar//
25350d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// For legacy support, we prefer a standard format, but will settle for a SW readable
25360d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// flex-YUV format.
25370d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnarstatus_t ACodec::setSupportedOutputFormat(bool getLegacyFlexibleFormat) {
25380d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    OMX_VIDEO_PARAM_PORTFORMATTYPE format, legacyFormat;
2539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
2540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = kPortIndexOutput;
2541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
25420d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    InitOMXParams(&legacyFormat);
25430d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    // this field will change when we find a suitable legacy format
25440d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    legacyFormat.eColorFormat = OMX_COLOR_FormatUnused;
2545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
25460d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    for (OMX_U32 index = 0; ; ++index) {
25470d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        format.nIndex = index;
25480d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        status_t err = mOMX->getParameter(
25490d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                mNode, OMX_IndexParamVideoPortFormat,
25500d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                &format, sizeof(format));
25510d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (err != OK) {
25520d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            // no more formats, pick legacy format if found
25530d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            if (legacyFormat.eColorFormat != OMX_COLOR_FormatUnused) {
25540d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                 memcpy(&format, &legacyFormat, sizeof(format));
25550d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                 break;
25560d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            }
25570d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            return err;
25580d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
25590d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (format.eCompressionFormat != OMX_VIDEO_CodingUnused) {
25600d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            return OMX_ErrorBadParameter;
25610d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
25620d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (!getLegacyFlexibleFormat) {
25630d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            break;
25640d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
25650d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        // standard formats that were exposed to users before
25660d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (format.eColorFormat == OMX_COLOR_FormatYUV420Planar
25670d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_COLOR_FormatYUV420PackedPlanar
25680d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar
25690d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_COLOR_FormatYUV420PackedSemiPlanar
25700d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar) {
25710d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            break;
25720d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
25730d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        // find best legacy non-standard format
25740d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        OMX_U32 flexibleEquivalent;
25750d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (legacyFormat.eColorFormat == OMX_COLOR_FormatUnused
25760d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && isFlexibleColorFormat(
25770d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        mOMX, mNode, format.eColorFormat, false /* usingNativeBuffers */,
25780d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        &flexibleEquivalent)
25790d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && flexibleEquivalent == OMX_COLOR_FormatYUV420Flexible) {
25800d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            memcpy(&legacyFormat, &format, sizeof(format));
25810d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
25820d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    }
2583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mOMX->setParameter(
2584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
2585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
2586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2588e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic const struct VideoCodingMapEntry {
2589e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    const char *mMime;
2590e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    OMX_VIDEO_CODINGTYPE mVideoCodingType;
2591e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber} kVideoCodingMapEntry[] = {
2592e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC },
25932472b1c0d63454e5d90a982bd6c555de6c3127bdRachad    { MEDIA_MIMETYPE_VIDEO_HEVC, OMX_VIDEO_CodingHEVC },
2594e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 },
2595e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 },
2596e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 },
259794705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 },
259894705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 },
2599e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber};
2600e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
26015778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic status_t GetVideoCodingTypeFromMime(
26025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
2603e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
2604e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
2605e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
2606e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) {
2607e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *codingType = kVideoCodingMapEntry[i].mVideoCodingType;
2608e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
2609e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
2610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2612e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    *codingType = OMX_VIDEO_CodingUnused;
2613e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2614e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
2615e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
2616e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2617e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic status_t GetMimeTypeForVideoCoding(
2618e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        OMX_VIDEO_CODINGTYPE codingType, AString *mime) {
2619e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
2620e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
2621e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
2622e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) {
2623e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *mime = kVideoCodingMapEntry[i].mMime;
2624e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
2625e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
2626e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
2627e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2628e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    mime->clear();
2629e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2630e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
26315778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
26325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26335778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoDecoder(
26340d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        const char *mime, const sp<AMessage> &msg, bool haveNativeWindow) {
263589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    int32_t width, height;
263689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    if (!msg->findInt32("width", &width)
263789869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            || !msg->findInt32("height", &height)) {
263889869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        return INVALID_OPERATION;
263989869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    }
264089869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar
26415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
26425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
26435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
26455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
26465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
2649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
2650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
265589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    int32_t tmp;
265689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    if (msg->findInt32("color-format", &tmp)) {
265789869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        OMX_COLOR_FORMATTYPE colorFormat =
265889869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            static_cast<OMX_COLOR_FORMATTYPE>(tmp);
265989869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        err = setVideoPortFormatType(
26600d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                kPortIndexOutput, OMX_VIDEO_CodingUnused, colorFormat, haveNativeWindow);
266189869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        if (err != OK) {
266289869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            ALOGW("[%s] does not support color format %d",
266389869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar                  mComponentName.c_str(), colorFormat);
26640d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            err = setSupportedOutputFormat(!haveNativeWindow /* getLegacyFlexibleFormat */);
266589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        }
266689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    } else {
26670d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        err = setSupportedOutputFormat(!haveNativeWindow /* getLegacyFlexibleFormat */);
266889869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    }
2669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
267478b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    int32_t frameRateInt;
267578b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    float frameRateFloat;
267678b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    if (!msg->findFloat("frame-rate", &frameRateFloat)) {
267778b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        if (!msg->findInt32("frame-rate", &frameRateInt)) {
267878b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            frameRateInt = -1;
267978b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        }
268078b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        frameRateFloat = (float)frameRateInt;
268178b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    }
268278b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad
2683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
268478b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            kPortIndexInput, width, height, compressionFormat, frameRateFloat);
2685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
2691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
2692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
27005778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) {
27015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
27025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("color-format", &tmp)) {
27035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
27045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_COLOR_FORMATTYPE colorFormat =
27075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        static_cast<OMX_COLOR_FORMATTYPE>(tmp);
27085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setVideoPortFormatType(
27105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
27115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
27135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support color format %d",
27145778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str(), colorFormat);
27155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
27175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Input port configuration */
27205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
27225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&def);
27235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
27255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexInput;
27275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
27295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
27305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
27325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
27335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t width, height, bitrate;
27365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("width", &width)
27375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("height", &height)
27385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("bitrate", &bitrate)) {
27395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
27405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
27435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
27445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t stride;
27465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("stride", &stride)) {
27475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        stride = width;
27485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nStride = stride;
27515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t sliceHeight;
27535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("slice-height", &sliceHeight)) {
27545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sliceHeight = height;
27555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nSliceHeight = sliceHeight;
27585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
27605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
27625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
27635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
27645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
27655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
27665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
27675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
27682c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        mTimePerFrameUs = (int64_t) (1000000.0f / frameRate);
27695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
27725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
2773a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    // this is redundant as it was already set up in setVideoPortFormatType
2774a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    // FIXME for now skip this only for flexible YUV formats
2775a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    if (colorFormat != OMX_COLOR_FormatYUV420Flexible) {
2776a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar        video_def->eColorFormat = colorFormat;
2777a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    }
27785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
27805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
27815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
27835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set input port definition parameters.",
27845778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
27855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
27875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Output port configuration */
27905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
27925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
27935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
27955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
27965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
27995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
28005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
28025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support compression format %d",
28035778822d86b0337407514b9372562b86edfa91cdAndreas Huber             mComponentName.c_str(), compressionFormat);
28045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
28065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexOutput;
28095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
28115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
28125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
28145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
28155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
28185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
28195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = 0;
28205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nBitrate = bitrate;
28215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = compressionFormat;
28225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = OMX_COLOR_FormatUnused;
28235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
28255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
28265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
28285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set output port definition parameters.",
28295778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
28305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
28325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (compressionFormat) {
28355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingMPEG4:
28365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupMPEG4EncoderParameters(msg);
28375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
28385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingH263:
28405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupH263EncoderParameters(msg);
28415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
28425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingAVC:
28445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupAVCEncoderParameters(msg);
28455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
28465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2847c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        case OMX_VIDEO_CodingHEVC:
2848c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            err = setupHEVCEncoderParameters(msg);
2849c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            break;
2850c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
285189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP8:
285289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP9:
285389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            err = setupVPXEncoderParameters(msg);
285489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            break;
285589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
28565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
28575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
28585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2860d36a023778256f0550e9a09e9993c066e8a3c7d7Ronghua Wu    if (err == OK) {
2861d36a023778256f0550e9a09e9993c066e8a3c7d7Ronghua Wu        ALOGI("setupVideoEncoder succeeded");
2862d36a023778256f0550e9a09e9993c066e8a3c7d7Ronghua Wu    }
28635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
28655778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
28665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28670dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dongstatus_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) {
28680dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    OMX_VIDEO_PARAM_INTRAREFRESHTYPE params;
28690dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    InitOMXParams(&params);
28700dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.nPortIndex = kPortIndexOutput;
28710dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
28720dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode);
28730dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
28740dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic ||
28750dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
28760dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
28770dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) {
28780dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
28790dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
28800dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nCirMBs = mbs;
28810dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
28820dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
28830dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive ||
28840dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
28850dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
28860dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) {
28870dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
28880dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
28890dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirMBs = mbs;
28900dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
28910dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t ref;
28920dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) {
28930dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
28940dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
28950dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirRef = ref;
28960dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
28970dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
28980dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = mOMX->setParameter(
28990dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            mNode, OMX_IndexParamVideoIntraRefresh,
29000dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            &params, sizeof(params));
29010dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    return err;
29020dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong}
29030dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
29045778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
29055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (iFramesInterval < 0) {
29065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0xFFFFFFFF;
29075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (iFramesInterval == 0) {
29085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0;
29095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_U32 ret = frameRate * iFramesInterval;
29115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return ret;
29125778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
29135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
291496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatic OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) {
291596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    int32_t tmp;
291696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    if (!msg->findInt32("bitrate-mode", &tmp)) {
291796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        return OMX_Video_ControlRateVariable;
291896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    }
291996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
292096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp);
292196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber}
292296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
29235778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
29245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
29255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
29265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
29275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
29285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
293096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
293196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
29325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
29335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
29345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
29355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
29365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
29375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
29385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
29395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
29425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&mpeg4type);
29435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPortIndex = kPortIndexOutput;
29445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
29465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
29475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
29495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
29505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nSliceHeaderSpacing = 0;
29535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bSVH = OMX_FALSE;
29545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bGov = OMX_FALSE;
29555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nAllowedPictureTypes =
29575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
29585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
29605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mpeg4type.nPFrames == 0) {
29615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
29625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nBFrames = 0;
29645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nIDCVLCThreshold = 0;
29655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bACPred = OMX_TRUE;
29665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nMaxPacketSize = 256;
29675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nTimeIncRes = 1000;
29685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nHeaderExtension = 0;
29695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bReversibleVLC = OMX_FALSE;
29705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
29725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
29735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
29745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
29755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
29765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
29775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
29795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
29815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
29825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
29835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
29855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
29865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
29895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
29905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
29925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
29935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
299596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
29965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
29985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
29995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
30005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
30025778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
30035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30045778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
30055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
30065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
30075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
30085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
30095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
30105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
301196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
301296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
30135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
30145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
30155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
30165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
30175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
30185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
30195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
30205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
30215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_H263TYPE h263type;
30235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h263type);
30245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPortIndex = kPortIndexOutput;
30255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
30275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
30285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
30305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
30315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
30325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nAllowedPictureTypes =
30345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
30355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
30375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h263type.nPFrames == 0) {
30385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
30395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
30405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nBFrames = 0;
30415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
30435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
30445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
30455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
30465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
30475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
30485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
30505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
30525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
30535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
30545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
30565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
30575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
30585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bPLUSPTYPEAllowed = OMX_FALSE;
30605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bForceRoundingTypeToZero = OMX_FALSE;
30615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPictureHeaderRepetition = 0;
30625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nGOBHeaderInterval = 0;
30635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
30655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
30665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
30685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
30695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
30705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
307196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
30725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
30745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
30755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
30765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
30785778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
30795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3080a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar// static
3081a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnarint /* OMX_VIDEO_AVCLEVELTYPE */ ACodec::getAVCLevelFor(
3082a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        int width, int height, int rate, int bitrate,
3083a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        OMX_VIDEO_AVCPROFILETYPE profile) {
3084a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    // convert bitrate to main/baseline profile kbps equivalent
3085a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    switch (profile) {
3086a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        case OMX_VIDEO_AVCProfileHigh10:
3087a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 3000); break;
3088a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        case OMX_VIDEO_AVCProfileHigh:
3089a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 1250); break;
3090a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        default:
3091a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 1000); break;
3092a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    }
3093a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
3094a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    // convert size and rate to MBs
3095a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    width = divUp(width, 16);
3096a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    height = divUp(height, 16);
3097a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    int mbs = width * height;
3098a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    rate *= mbs;
3099a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    int maxDimension = max(width, height);
3100a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
3101a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    static const int limits[][5] = {
3102a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        /*   MBps     MB   dim  bitrate        level */
3103a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    1485,    99,  28,     64, OMX_VIDEO_AVCLevel1  },
3104a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    1485,    99,  28,    128, OMX_VIDEO_AVCLevel1b },
3105a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    3000,   396,  56,    192, OMX_VIDEO_AVCLevel11 },
3106a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    6000,   396,  56,    384, OMX_VIDEO_AVCLevel12 },
3107a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   11880,   396,  56,    768, OMX_VIDEO_AVCLevel13 },
3108a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   11880,   396,  56,   2000, OMX_VIDEO_AVCLevel2  },
3109a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   19800,   792,  79,   4000, OMX_VIDEO_AVCLevel21 },
3110a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   20250,  1620, 113,   4000, OMX_VIDEO_AVCLevel22 },
3111a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   40500,  1620, 113,  10000, OMX_VIDEO_AVCLevel3  },
3112a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  108000,  3600, 169,  14000, OMX_VIDEO_AVCLevel31 },
3113a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  216000,  5120, 202,  20000, OMX_VIDEO_AVCLevel32 },
3114a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  245760,  8192, 256,  20000, OMX_VIDEO_AVCLevel4  },
3115a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  245760,  8192, 256,  50000, OMX_VIDEO_AVCLevel41 },
3116a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  522240,  8704, 263,  50000, OMX_VIDEO_AVCLevel42 },
3117a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  589824, 22080, 420, 135000, OMX_VIDEO_AVCLevel5  },
3118a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  983040, 36864, 543, 240000, OMX_VIDEO_AVCLevel51 },
3119a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        { 2073600, 36864, 543, 240000, OMX_VIDEO_AVCLevel52 },
3120a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    };
3121a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
3122a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    for (size_t i = 0; i < ARRAY_SIZE(limits); i++) {
3123a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        const int (&limit)[5] = limits[i];
3124a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        if (rate <= limit[0] && mbs <= limit[1] && maxDimension <= limit[2]
3125a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar                && bitrate <= limit[3]) {
3126a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            return limit[4];
3127a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        }
3128a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    }
3129a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    return 0;
3130a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar}
3131a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
31325778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
31335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
31345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
31355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
31365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
31375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
31385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
313996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
314096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
31415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
31425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
31435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
31445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
31455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
31465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
31475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
31485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
31495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31500dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = OK;
31510dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    int32_t intraRefreshMode = 0;
31520dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) {
31530dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode);
31540dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (err != OK) {
31550dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
31560dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong                    err, intraRefreshMode);
31570dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return err;
31580dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
31590dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
31600dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
31615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_AVCTYPE h264type;
31625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h264type);
31635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nPortIndex = kPortIndexOutput;
31645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31650dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    err = mOMX->getParameter(
31665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
31675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
31695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
31705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
31715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nAllowedPictureTypes =
31735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
31745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
31765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
31775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
31785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
31795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
31805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
31815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
31835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
31855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
31865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
31875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
31895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
31905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
31915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // XXX
31937c25df82dfc8bbedb58608242f0d923a4594bb14James Dong    if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) {
31947c25df82dfc8bbedb58608242f0d923a4594bb14James Dong        ALOGW("Use baseline profile instead of %d for AVC recording",
31957c25df82dfc8bbedb58608242f0d923a4594bb14James Dong            h264type.eProfile);
31965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
31975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
31985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
32005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nSliceHeaderSpacing = 0;
32015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bUseHadamard = OMX_TRUE;
32025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefFrames = 1;
32035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nBFrames = 0;
32045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
32055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (h264type.nPFrames == 0) {
32065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
32075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
32085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx10ActiveMinus1 = 0;
32095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx11ActiveMinus1 = 0;
32105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bEntropyCodingCABAC = OMX_FALSE;
32115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bWeightedPPrediction = OMX_FALSE;
32125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bconstIpred = OMX_FALSE;
32135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirect8x8Inference = OMX_FALSE;
32145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirectSpatialTemporal = OMX_FALSE;
32155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nCabacInitIdc = 0;
32165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
32175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.nBFrames != 0) {
32195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
32205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
32215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableUEP = OMX_FALSE;
32235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableFMO = OMX_FALSE;
32245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableASO = OMX_FALSE;
32255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableRS = OMX_FALSE;
32265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bFrameMBsOnly = OMX_TRUE;
32275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bMBAFF = OMX_FALSE;
32285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
32295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
32315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
32325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
32345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
32355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
32365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
323796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return configureBitrate(bitrate, bitrateMode);
32385778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
32395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3240c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachadstatus_t ACodec::setupHEVCEncoderParameters(const sp<AMessage> &msg) {
3241c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    int32_t bitrate, iFrameInterval;
3242c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findInt32("bitrate", &bitrate)
3243c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
3244c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return INVALID_OPERATION;
3245c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
3246c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3247c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
3248c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3249c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    float frameRate;
3250c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findFloat("frame-rate", &frameRate)) {
3251c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t tmp;
3252c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("frame-rate", &tmp)) {
3253c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
3254c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
3255c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        frameRate = (float)tmp;
3256c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
3257c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3258c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_PARAM_HEVCTYPE hevcType;
3259c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    InitOMXParams(&hevcType);
3260c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    hevcType.nPortIndex = kPortIndexOutput;
3261c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3262c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    status_t err = OK;
3263c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    err = mOMX->getParameter(
3264c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
3265c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
3266c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
3267c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
3268c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3269c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    int32_t profile;
3270c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (msg->findInt32("profile", &profile)) {
3271c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t level;
3272c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("level", &level)) {
3273c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
3274c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
3275c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3276c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        err = verifySupportForProfileAndLevel(profile, level);
3277c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (err != OK) {
3278c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return err;
3279c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
3280c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3281c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eProfile = static_cast<OMX_VIDEO_HEVCPROFILETYPE>(profile);
3282c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eLevel = static_cast<OMX_VIDEO_HEVCLEVELTYPE>(level);
3283c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
3284c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3285c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    // TODO: Need OMX structure definition for setting iFrameInterval
3286c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3287c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    err = mOMX->setParameter(
3288c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
3289c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
3290c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
3291c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
3292c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3293c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    return configureBitrate(bitrate, bitrateMode);
3294c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad}
3295c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
329689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huberstatus_t ACodec::setupVPXEncoderParameters(const sp<AMessage> &msg) {
329789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    int32_t bitrate;
32984154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    int32_t iFrameInterval = 0;
32994154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    size_t tsLayers = 0;
33004154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE pattern =
33014154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        OMX_VIDEO_VPXTemporalLayerPatternNone;
33024154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    static const uint32_t kVp8LayerRateAlloction
33034154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS]
33044154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS] = {
33054154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        {100, 100, 100},  // 1 layer
33064154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 60, 100, 100},  // 2 layers {60%, 40%}
33074154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 40,  60, 100},  // 3 layers {40%, 20%, 40%}
33084154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    };
330989b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    if (!msg->findInt32("bitrate", &bitrate)) {
331089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        return INVALID_OPERATION;
331189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    }
33124154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    msg->findInt32("i-frame-interval", &iFrameInterval);
331389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
331489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
331589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
33164154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    float frameRate;
33174154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (!msg->findFloat("frame-rate", &frameRate)) {
33184154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        int32_t tmp;
33194154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (!msg->findInt32("frame-rate", &tmp)) {
33204154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            return INVALID_OPERATION;
33214154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
33224154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        frameRate = (float)tmp;
33234154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
33244154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
33254154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    AString tsSchema;
33264154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (msg->findString("ts-schema", &tsSchema)) {
33274154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (tsSchema == "webrtc.vp8.1-layer") {
33284154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
33294154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 1;
33304154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else if (tsSchema == "webrtc.vp8.2-layer") {
33314154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
33324154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 2;
33334154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else if (tsSchema == "webrtc.vp8.3-layer") {
33344154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
33354154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 3;
33364154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else {
33374154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            ALOGW("Unsupported ts-schema [%s]", tsSchema.c_str());
33384154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
33394154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
33404154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
33414154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
33424154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    InitOMXParams(&vp8type);
33434154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    vp8type.nPortIndex = kPortIndexOutput;
33444154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    status_t err = mOMX->getParameter(
33454154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
33464154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            &vp8type, sizeof(vp8type));
33474154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
33484154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (err == OK) {
33494154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (iFrameInterval > 0) {
33504154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nKeyFrameInterval = setPFramesSpacing(iFrameInterval, frameRate);
33514154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
33524154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.eTemporalPattern = pattern;
33534154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.nTemporalLayerCount = tsLayers;
33544154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (tsLayers > 0) {
33554154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            for (size_t i = 0; i < OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS; i++) {
33564154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                vp8type.nTemporalLayerBitrateRatio[i] =
33574154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                    kVp8LayerRateAlloction[tsLayers - 1][i];
33584154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            }
33594154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
33604154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (bitrateMode == OMX_Video_ControlRateConstant) {
33614154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMinQuantizer = 2;
33624154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMaxQuantizer = 63;
33634154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
33644154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
33654154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        err = mOMX->setParameter(
33664154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
33674154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                &vp8type, sizeof(vp8type));
33684154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (err != OK) {
33694154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            ALOGW("Extended VP8 parameters set failed: %d", err);
33704154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
33714154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
33724154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
337389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    return configureBitrate(bitrate, bitrateMode);
337489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber}
337589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
33765778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::verifySupportForProfileAndLevel(
33775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t profile, int32_t level) {
33785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
33795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&params);
33805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    params.nPortIndex = kPortIndexOutput;
33815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (params.nProfileIndex = 0;; ++params.nProfileIndex) {
33835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
33845778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode,
33855778822d86b0337407514b9372562b86edfa91cdAndreas Huber                OMX_IndexParamVideoProfileLevelQuerySupported,
33865778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &params,
33875778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sizeof(params));
33885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
33905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
33915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
33925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
33945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
33955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (profile == supportedProfile && level <= supportedLevel) {
33975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OK;
33985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
33995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
34005778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
34015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
340296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatus_t ACodec::configureBitrate(
340396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) {
34045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
34055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&bitrateType);
34065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
34075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
34095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
34105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
34115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
34135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
34145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
34155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
341696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    bitrateType.eControlRate = bitrateMode;
34175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nTargetBitrate = bitrate;
34185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
34205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
34215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
34225778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
34235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34245778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupErrorCorrectionParameters() {
34255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
34265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&errorCorrectionType);
34275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nPortIndex = kPortIndexOutput;
34285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
34305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
34315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
34325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
34345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OK;  // Optional feature. Ignore this failure
34355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
34365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableHEC = OMX_FALSE;
34385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableResync = OMX_TRUE;
34395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nResynchMarkerSpacing = 256;
34405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
34415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableRVLC = OMX_FALSE;
34425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
34445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
34455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
34465778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
34475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3448f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoFormatOnPort(
3449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
345078b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat,
345178b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        float frameRate) {
3452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
3453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
3454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
3455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
3457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
3459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
3460777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (err != OK) {
3461777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return err;
3462777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
3463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
3465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // XXX Need a (much) better heuristic to compute input buffer sizes.
3466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const size_t X = 64 * 1024;
3467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (def.nBufferSize < X) {
3468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.nBufferSize = X;
3469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3472777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (def.eDomain != OMX_PortDomainVideo) {
3473777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("expected video port, got %s(%d)", asString(def.eDomain), def.eDomain);
3474777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return FAILED_TRANSACTION;
3475777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
3476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameWidth = width;
3478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameHeight = height;
3479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
3481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eCompressionFormat = compressionFormat;
3482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eColorFormat = OMX_COLOR_FormatUnused;
348378b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        if (frameRate >= 0) {
348478b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
348578b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        }
3486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
3489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
3490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
3492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3494f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::initNativeWindow() {
3495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL) {
3496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
3497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
3500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
3501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3503d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Hubersize_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
3504d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    size_t n = 0;
3505d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
3506d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
3507d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        const BufferInfo &info = mBuffers[portIndex].itemAt(i);
3508d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
3509d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
3510d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            ++n;
3511d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        }
3512d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    }
3513d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
3514d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    return n;
3515d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber}
3516d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
35177e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubersize_t ACodec::countBuffersOwnedByNativeWindow() const {
35187e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    size_t n = 0;
35197e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
35207e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
35217e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
35227e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
35237e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
35247e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            ++n;
35257e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        }
35267e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
35277e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
35287e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    return n;
35297e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
35307e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
35317e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubervoid ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
35327e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (mNativeWindow == NULL) {
35337e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        return;
35347e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
35357e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
3536e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    while (countBuffersOwnedByNativeWindow() > mNumUndequeuedBuffers
35377e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            && dequeueBufferFromNativeWindow() != NULL) {
3538c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        // these buffers will be submitted as regular buffers; account for this
3539c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        if (mStoreMetaDataInOutputBuffers && mMetaDataBuffersToSubmit > 0) {
3540c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar            --mMetaDataBuffersToSubmit;
3541c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        }
35427e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
35437e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
35447e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
3545f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs(
3546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
3547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
3548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
3549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus != BufferInfo::OWNED_BY_US
3551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3552609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGV("[%s] Buffer %u on port %u still has status %d",
3553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mComponentName.c_str(),
3554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info->mBufferID, portIndex, info->mStatus);
3555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
3556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3562f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs() {
3563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return allYourBuffersAreBelongToUs(kPortIndexInput)
3564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        && allYourBuffersAreBelongToUs(kPortIndexOutput);
3565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3567f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::deferMessage(const sp<AMessage> &msg) {
3568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.push_back(msg);
3569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3571f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::processDeferredMessages() {
3572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> > queue = mDeferredQueue;
3573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.clear();
3574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> >::iterator it = queue.begin();
3576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while (it != queue.end()) {
3577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        onMessageReceived(*it++);
3578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
358103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar// static
3582229d242665c612fd97431d1e7ac004823b47f181Lajos Molnarbool ACodec::describeDefaultColorFormat(DescribeColorFormatParams &params) {
358303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    MediaImage &image = params.sMediaImage;
358403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    memset(&image, 0, sizeof(image));
358503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
358603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mType = MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
358703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mNumPlanes = 0;
358803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
358903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    const OMX_COLOR_FORMATTYPE fmt = params.eColorFormat;
359003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mWidth = params.nFrameWidth;
359103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mHeight = params.nFrameHeight;
359203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
359303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    // only supporting YUV420
359403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    if (fmt != OMX_COLOR_FormatYUV420Planar &&
359503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        fmt != OMX_COLOR_FormatYUV420PackedPlanar &&
359603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        fmt != OMX_COLOR_FormatYUV420SemiPlanar &&
35975a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        fmt != OMX_COLOR_FormatYUV420PackedSemiPlanar &&
35985a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        fmt != HAL_PIXEL_FORMAT_YV12) {
359903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        ALOGW("do not know color format 0x%x = %d", fmt, fmt);
3600229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return false;
360103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    }
360203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
3603b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    // TEMPORARY FIX for some vendors that advertise sliceHeight as 0
3604b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    if (params.nStride != 0 && params.nSliceHeight == 0) {
3605b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        ALOGW("using sliceHeight=%u instead of what codec advertised (=0)",
3606b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar                params.nFrameHeight);
3607b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        params.nSliceHeight = params.nFrameHeight;
3608b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    }
3609b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar
3610b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    // we need stride and slice-height to be non-zero
3611b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    if (params.nStride == 0 || params.nSliceHeight == 0) {
3612b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        ALOGW("cannot describe color format 0x%x = %d with stride=%u and sliceHeight=%u",
3613b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar                fmt, fmt, params.nStride, params.nSliceHeight);
3614b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        return false;
3615b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    }
3616b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar
361703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    // set-up YUV format
361803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mType = MediaImage::MEDIA_IMAGE_TYPE_YUV;
361903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mNumPlanes = 3;
362003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mBitDepth = 8;
362103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mOffset = 0;
362203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mColInc = 1;
362303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mRowInc = params.nStride;
362403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mHorizSubsampling = 1;
362503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mVertSubsampling = 1;
362603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
36275a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar    switch ((int)fmt) {
36285a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        case HAL_PIXEL_FORMAT_YV12:
36295a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            if (params.bUsingNativeBuffers) {
36305a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                size_t ystride = align(params.nStride, 16);
36315a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                size_t cstride = align(params.nStride / 2, 16);
36325a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.Y].mRowInc = ystride;
36335a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
36345a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mOffset = ystride * params.nSliceHeight;
36355a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mColInc = 1;
36365a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mRowInc = cstride;
36375a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mHorizSubsampling = 2;
36385a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mVertSubsampling = 2;
36395a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
36405a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mOffset = image.mPlane[image.V].mOffset
36415a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                        + (cstride * params.nSliceHeight / 2);
36425a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mColInc = 1;
36435a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mRowInc = cstride;
36445a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mHorizSubsampling = 2;
36455a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mVertSubsampling = 2;
36465a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                break;
36475a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            } else {
36485a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                // fall through as YV12 is used for YUV420Planar by some codecs
36495a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            }
36505a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
36515a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        case OMX_COLOR_FormatYUV420Planar:
365203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420PackedPlanar:
365303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight;
365403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mColInc = 1;
365503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mRowInc = params.nStride / 2;
365603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mHorizSubsampling = 2;
365703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mVertSubsampling = 2;
365803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
365903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset
366003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    + (params.nStride * params.nSliceHeight / 4);
366103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mColInc = 1;
366203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mRowInc = params.nStride / 2;
366303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mHorizSubsampling = 2;
366403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mVertSubsampling = 2;
366503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            break;
366603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
366703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420SemiPlanar:
366803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            // FIXME: NV21 for sw-encoder, NV12 for decoder and hw-encoder
366903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420PackedSemiPlanar:
367003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            // NV12
367103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight;
367203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mColInc = 2;
367303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mRowInc = params.nStride;
367403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mHorizSubsampling = 2;
367503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mVertSubsampling = 2;
367603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
367703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset + 1;
367803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mColInc = 2;
367903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mRowInc = params.nStride;
368003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mHorizSubsampling = 2;
368103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mVertSubsampling = 2;
368203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            break;
368303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
368403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        default:
368503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            TRESPASS();
368603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    }
3687229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    return true;
3688229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar}
3689229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3690229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar// static
3691229d242665c612fd97431d1e7ac004823b47f181Lajos Molnarbool ACodec::describeColorFormat(
3692229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        const sp<IOMX> &omx, IOMX::node_id node,
3693229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        DescribeColorFormatParams &describeParams)
3694229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar{
3695229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    OMX_INDEXTYPE describeColorFormatIndex;
3696229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    if (omx->getExtensionIndex(
3697229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            node, "OMX.google.android.index.describeColorFormat",
3698229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            &describeColorFormatIndex) != OK ||
3699229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        omx->getParameter(
3700229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            node, describeColorFormatIndex,
3701229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            &describeParams, sizeof(describeParams)) != OK) {
3702229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return describeDefaultColorFormat(describeParams);
3703229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    }
3704229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    return describeParams.sMediaImage.mType !=
3705229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
3706229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar}
3707229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3708229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar// static
3709229d242665c612fd97431d1e7ac004823b47f181Lajos Molnarbool ACodec::isFlexibleColorFormat(
3710229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar         const sp<IOMX> &omx, IOMX::node_id node,
37110d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar         uint32_t colorFormat, bool usingNativeBuffers, OMX_U32 *flexibleEquivalent) {
3712229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    DescribeColorFormatParams describeParams;
3713229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    InitOMXParams(&describeParams);
3714229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.eColorFormat = (OMX_COLOR_FORMATTYPE)colorFormat;
3715229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    // reasonable dummy values
3716229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nFrameWidth = 128;
3717229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nFrameHeight = 128;
3718229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nStride = 128;
3719229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nSliceHeight = 128;
37200d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    describeParams.bUsingNativeBuffers = (OMX_BOOL)usingNativeBuffers;
3721229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3722229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    CHECK(flexibleEquivalent != NULL);
3723229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3724229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    if (!describeColorFormat(omx, node, describeParams)) {
3725229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return false;
3726229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    }
3727229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3728229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    const MediaImage &img = describeParams.sMediaImage;
3729229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    if (img.mType == MediaImage::MEDIA_IMAGE_TYPE_YUV) {
3730229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        if (img.mNumPlanes != 3 ||
3731229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            img.mPlane[img.Y].mHorizSubsampling != 1 ||
3732229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            img.mPlane[img.Y].mVertSubsampling != 1) {
3733229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            return false;
3734229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
3735229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3736229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        // YUV 420
3737229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        if (img.mPlane[img.U].mHorizSubsampling == 2
3738229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.U].mVertSubsampling == 2
3739229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.V].mHorizSubsampling == 2
3740229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.V].mVertSubsampling == 2) {
3741229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            // possible flexible YUV420 format
3742229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            if (img.mBitDepth <= 8) {
3743229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar               *flexibleEquivalent = OMX_COLOR_FormatYUV420Flexible;
3744229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar               return true;
3745229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            }
3746229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
3747229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    }
3748229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    return false;
374903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar}
375003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
3751e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarstatus_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> &notify) {
3752777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    const char *niceIndex = portIndex == kPortIndexInput ? "input" : "output";
375331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
375431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    InitOMXParams(&def);
3755e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    def.nPortIndex = portIndex;
375631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3757777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    status_t err = mOMX->getParameter(mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
3758777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (err != OK) {
3759777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return err;
3760777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
376131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3762777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (def.eDir != (portIndex == kPortIndexOutput ? OMX_DirOutput : OMX_DirInput)) {
3763777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("unexpected dir: %s(%d) on %s port", asString(def.eDir), def.eDir, niceIndex);
3764777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return BAD_VALUE;
3765777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
376631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
376731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    switch (def.eDomain) {
376831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainVideo:
376931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
377031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
3771e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            switch ((int)videoDef->eCompressionFormat) {
3772e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_VIDEO_CodingUnused:
3773e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3774e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(mIsEncoder ^ (portIndex == kPortIndexOutput));
3775e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
3776e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3777e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("stride", videoDef->nStride);
3778e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("slice-height", videoDef->nSliceHeight);
3779e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("color-format", videoDef->eColorFormat);
3780e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
37810d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                    if (mNativeWindow == NULL) {
37820d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        DescribeColorFormatParams describeParams;
37830d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        InitOMXParams(&describeParams);
37840d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.eColorFormat = videoDef->eColorFormat;
37850d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nFrameWidth = videoDef->nFrameWidth;
37860d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nFrameHeight = videoDef->nFrameHeight;
37870d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nStride = videoDef->nStride;
37880d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nSliceHeight = videoDef->nSliceHeight;
37890d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.bUsingNativeBuffers = OMX_FALSE;
37900d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar
37910d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        if (describeColorFormat(mOMX, mNode, describeParams)) {
37920d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                            notify->setBuffer(
37930d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                    "image-data",
37940d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                    ABuffer::CreateAsCopy(
37950d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                            &describeParams.sMediaImage,
37960d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                            sizeof(describeParams.sMediaImage)));
37975a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
37985a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                            MediaImage *img = &describeParams.sMediaImage;
37995a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                            ALOGV("[%s] MediaImage { F(%zux%zu) @%zu+%zu+%zu @%zu+%zu+%zu @%zu+%zu+%zu }",
38005a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                                    mComponentName.c_str(), img->mWidth, img->mHeight,
38015a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                                    img->mPlane[0].mOffset, img->mPlane[0].mColInc, img->mPlane[0].mRowInc,
38025a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                                    img->mPlane[1].mOffset, img->mPlane[1].mColInc, img->mPlane[1].mRowInc,
38035a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                                    img->mPlane[2].mOffset, img->mPlane[2].mColInc, img->mPlane[2].mRowInc);
38040d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        }
380503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    }
380603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
380791a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                    if (portIndex != kPortIndexOutput) {
380891a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                        // TODO: also get input crop
380991a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                        break;
381091a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                    }
381191a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar
3812e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_CONFIG_RECTTYPE rect;
3813e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&rect);
381491a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                    rect.nPortIndex = portIndex;
3815e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3816e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    if (mOMX->getConfig(
381791a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                mNode,
381891a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                (portIndex == kPortIndexOutput ?
381991a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                        OMX_IndexConfigCommonOutputCrop :
382091a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                        OMX_IndexConfigCommonInputCrop),
3821e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &rect, sizeof(rect)) != OK) {
3822e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nLeft = 0;
3823e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nTop = 0;
3824e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nWidth = videoDef->nFrameWidth;
3825e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nHeight = videoDef->nFrameHeight;
3826e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    }
382731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3828777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (rect.nLeft < 0 ||
3829777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        rect.nTop < 0 ||
3830777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        rect.nLeft + rect.nWidth > videoDef->nFrameWidth ||
3831777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        rect.nTop + rect.nHeight > videoDef->nFrameHeight) {
3832777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        ALOGE("Wrong cropped rect (%d, %d) - (%u, %u) vs. frame (%u, %u)",
3833777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                rect.nLeft, rect.nTop,
3834777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                rect.nLeft + rect.nWidth, rect.nTop + rect.nHeight,
3835777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                videoDef->nFrameWidth, videoDef->nFrameHeight);
3836777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return BAD_VALUE;
3837777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
3838e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3839e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setRect(
3840577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            "crop",
3841577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nLeft,
3842577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nTop,
3843e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                            rect.nLeft + rect.nWidth - 1,
3844e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                            rect.nTop + rect.nHeight - 1);
3845e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3846e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3847e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
38484730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
38494730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP8:
38504730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP9:
38514730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                {
38524730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
38534730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    InitOMXParams(&vp8type);
38544730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    vp8type.nPortIndex = kPortIndexOutput;
38554730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    status_t err = mOMX->getParameter(
38564730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            mNode,
38574730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
38584730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            &vp8type,
38594730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            sizeof(vp8type));
38604730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
38614730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    if (err == OK) {
38624730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        AString tsSchema = "none";
38634730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        if (vp8type.eTemporalPattern
38644730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                == OMX_VIDEO_VPXTemporalLayerPatternWebRTC) {
38654730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            switch (vp8type.nTemporalLayerCount) {
38664730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 1:
38674730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
38684730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.1-layer";
38694730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
38704730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
38714730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 2:
38724730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
38734730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.2-layer";
38744730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
38754730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
38764730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 3:
38774730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
38784730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.3-layer";
38794730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
38804730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
38814730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                default:
38824730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
38834730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
38844730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
38854730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            }
38864730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        }
38874730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        notify->setString("ts-schema", tsSchema);
38884730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    }
38894730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    // Fall through to set up mime.
38904730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                }
38914730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
3892e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                default:
3893e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3894777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (mIsEncoder ^ (portIndex == kPortIndexOutput)) {
3895777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        // should be CodingUnused
3896777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        ALOGE("Raw port video compression format is %s(%d)",
3897777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                asString(videoDef->eCompressionFormat),
3898777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                videoDef->eCompressionFormat);
3899777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return BAD_VALUE;
3900777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
3901e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    AString mime;
3902e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    if (GetMimeTypeForVideoCoding(
3903e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        videoDef->eCompressionFormat, &mime) != OK) {
3904e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", "application/octet-stream");
3905e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    } else {
3906e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", mime.c_str());
3907e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    }
3908e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3909e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
391031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            }
3911e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("width", videoDef->nFrameWidth);
3912e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("height", videoDef->nFrameHeight);
39135a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            ALOGV("[%s] %s format is %s", mComponentName.c_str(),
39145a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                    portIndex == kPortIndexInput ? "input" : "output",
39155a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                    notify->debugString().c_str());
39165a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
391731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
391831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
391931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
392031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainAudio:
392131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
392231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
392331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
392497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            switch ((int)audioDef->eEncoding) {
3925e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingPCM:
3926e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3927e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_PCMMODETYPE params;
3928e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3929e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3930e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3931777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
3932777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, OMX_IndexParamAudioPcm, &params, sizeof(params));
3933777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
3934777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
3935777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
393614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
3937777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (params.nChannels <= 0
3938777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            || (params.nChannels != 1 && !params.bInterleaved)
3939777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            || params.nBitPerSample != 16u
3940777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            || params.eNumData != OMX_NumericalDataSigned
3941777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            || params.ePCMMode != OMX_AUDIO_PCMModeLinear) {
3942777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        ALOGE("unsupported PCM port: %u channels%s, %u-bit, %s(%d), %s(%d) mode ",
3943777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                params.nChannels,
3944777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                params.bInterleaved ? " interleaved" : "",
3945777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                params.nBitPerSample,
3946777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                asString(params.eNumData), params.eNumData,
3947777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                asString(params.ePCMMode), params.ePCMMode);
3948777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return FAILED_TRANSACTION;
3949777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
3950e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3951e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
3952e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
3953e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSamplingRate);
3954e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3955e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mChannelMaskPresent) {
3956e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("channel-mask", mChannelMask);
39578b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                    }
3958e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
39598b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                }
39609806555d3930be43e11106281dee354820ac1c88Andreas Huber
3961e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAAC:
3962e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3963e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AACPROFILETYPE params;
3964e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3965e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3966e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3967777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
3968777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, OMX_IndexParamAudioAac, &params, sizeof(params));
3969777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
3970777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
3971777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
3972e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3973e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
3974e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
3975e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
3976e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
3977e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
3978e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3979e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAMR:
3980e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3981e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AMRTYPE params;
3982e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3983e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
39849806555d3930be43e11106281dee354820ac1c88Andreas Huber
3985777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
3986777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, OMX_IndexParamAudioAmr, &params, sizeof(params));
3987777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
3988777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
3989777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
3990e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3991e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", 1);
3992e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) {
39930806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_WB);
3994e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 16000);
3995e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    } else {
39960806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
3997e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 8000);
3998e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
3999e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
4000e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
4001e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4002e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingFLAC:
4003e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
4004e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_FLACTYPE params;
4005e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
4006e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
4007e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4008777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4009777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, OMX_IndexParamAudioFlac, &params, sizeof(params));
4010777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4011777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4012777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4013e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4014e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC);
4015e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
4016e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
4017e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
4018e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
4019e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4020e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingMP3:
4021e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
4022e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_MP3TYPE params;
4023e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
4024e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
4025e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4026777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4027777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, OMX_IndexParamAudioMp3, &params, sizeof(params));
4028777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4029777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4030777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4031e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4032e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MPEG);
4033e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
4034e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
4035e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
4036e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
4037e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4038e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingVORBIS:
4039e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
4040e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_VORBISTYPE params;
4041e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
4042e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
4043e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4044777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4045777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, OMX_IndexParamAudioVorbis, &params, sizeof(params));
4046777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4047777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4048777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4049e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4050e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_VORBIS);
4051e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
4052e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
4053e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
4054e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
4055e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
405697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                case OMX_AUDIO_CodingAndroidAC3:
405797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                {
405897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    OMX_AUDIO_PARAM_ANDROID_AC3TYPE params;
405997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    InitOMXParams(&params);
4060e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
406197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
4062777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4063777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
4064777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            &params, sizeof(params));
4065777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4066777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4067777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
406897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
406997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AC3);
407097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("channel-count", params.nChannels);
407197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("sample-rate", params.nSampleRate);
407297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    break;
407397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                }
4074e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
40758a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                case OMX_AUDIO_CodingAndroidEAC3:
40768a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                {
40778a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    OMX_AUDIO_PARAM_ANDROID_EAC3TYPE params;
40788a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    InitOMXParams(&params);
40798a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    params.nPortIndex = portIndex;
40808a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
4081777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4082777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
4083777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            &params, sizeof(params));
4084777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4085777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4086777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
40878a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
40888a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_EAC3);
40898a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setInt32("channel-count", params.nChannels);
40908a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setInt32("sample-rate", params.nSampleRate);
40918a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    break;
40928a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                }
40938a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
40948c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                case OMX_AUDIO_CodingAndroidOPUS:
40958c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                {
40968c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    OMX_AUDIO_PARAM_ANDROID_OPUSTYPE params;
40978c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    InitOMXParams(&params);
40988c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    params.nPortIndex = portIndex;
40998c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
4100777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4101777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus,
4102777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            &params, sizeof(params));
4103777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4104777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4105777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
41068c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
41078c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_OPUS);
41088c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("channel-count", params.nChannels);
41098c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("sample-rate", params.nSampleRate);
41108c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    break;
41118c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                }
41128c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
411310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                case OMX_AUDIO_CodingG711:
411410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                {
411510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    OMX_AUDIO_PARAM_PCMMODETYPE params;
411610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    InitOMXParams(&params);
411710d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    params.nPortIndex = portIndex;
411810d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
4119777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4120777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioPcm, &params, sizeof(params));
4121777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4122777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4123777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
412410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
412510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    const char *mime = NULL;
412610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    if (params.ePCMMode == OMX_AUDIO_PCMModeMULaw) {
412710d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_G711_MLAW;
412810d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    } else if (params.ePCMMode == OMX_AUDIO_PCMModeALaw) {
412910d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_G711_ALAW;
413010d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    } else { // params.ePCMMode == OMX_AUDIO_PCMModeLinear
413110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_RAW;
413210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    }
413310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setString("mime", mime);
413410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setInt32("channel-count", params.nChannels);
413510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setInt32("sample-rate", params.nSamplingRate);
413610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    break;
413710d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                }
413841d3f579d2c166984958263533284209b90c87d5Marco Nelissen
413941d3f579d2c166984958263533284209b90c87d5Marco Nelissen                case OMX_AUDIO_CodingGSMFR:
414041d3f579d2c166984958263533284209b90c87d5Marco Nelissen                {
41410806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    OMX_AUDIO_PARAM_PCMMODETYPE params;
414241d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    InitOMXParams(&params);
414341d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    params.nPortIndex = portIndex;
414441d3f579d2c166984958263533284209b90c87d5Marco Nelissen
4145777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4146777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                mNode, OMX_IndexParamAudioPcm, &params, sizeof(params));
4147777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4148777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4149777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
415041d3f579d2c166984958263533284209b90c87d5Marco Nelissen
415141d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MSGSM);
415241d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    notify->setInt32("channel-count", params.nChannels);
41530806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    notify->setInt32("sample-rate", params.nSamplingRate);
415441d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    break;
415510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                }
415610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
4157e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                default:
4158777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGE("Unsupported audio coding: %s(%d)\n",
4159777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            asString(audioDef->eEncoding), audioDef->eEncoding);
4160777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return BAD_TYPE;
4161e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
416231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
416331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
416431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
416531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        default:
4166777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("Unsupported domain: %s(%d)", asString(def.eDomain), def.eDomain);
4167777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return BAD_TYPE;
416831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    }
416931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4170e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    return OK;
4171e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar}
4172e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4173e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarvoid ACodec::sendFormatChange(const sp<AMessage> &reply) {
41744e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    sp<AMessage> notify = mBaseOutputFormat->dup();
4175e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    notify->setInt32("what", kWhatOutputFormatChanged);
4176e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4177777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (getPortFormat(kPortIndexOutput, notify) != OK) {
4178777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("[%s] Failed to get port format to send format change", mComponentName.c_str());
4179777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return;
4180777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
4181e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4182e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    AString mime;
4183e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK(notify->findString("mime", &mime));
4184e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4185e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    int32_t left, top, right, bottom;
4186e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if (mime == MEDIA_MIMETYPE_VIDEO_RAW &&
4187e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        mNativeWindow != NULL &&
4188e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->findRect("crop", &left, &top, &right, &bottom)) {
4189e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        // notify renderer of the crop change
4190e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        // NOTE: native window uses extended right-bottom coordinate
4191e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        reply->setRect("crop", left, top, right + 1, bottom + 1);
4192e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    } else if (mime == MEDIA_MIMETYPE_AUDIO_RAW &&
4193e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar               (mEncoderDelay || mEncoderPadding)) {
4194e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        int32_t channelCount;
4195e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        CHECK(notify->findInt32("channel-count", &channelCount));
4196e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        size_t frameSize = channelCount * sizeof(int16_t);
4197e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        if (mSkipCutBuffer != NULL) {
4198e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            size_t prevbufsize = mSkipCutBuffer->size();
4199e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            if (prevbufsize != 0) {
4200ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                ALOGW("Replacing SkipCutBuffer holding %zu bytes", prevbufsize);
4201e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            }
4202e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        }
4203e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        mSkipCutBuffer = new SkipCutBuffer(
4204e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                mEncoderDelay * frameSize,
4205e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                mEncoderPadding * frameSize);
4206e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
4207e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
420831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->post();
420931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
421031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mSentFormat = true;
421131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber}
421231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
42135778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
4214cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    sp<AMessage> notify = mNotify->dup();
4215d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatError);
4216251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    ALOGE("signalError(omxError %#x, internalError %d)", error, internalError);
4217251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
4218251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (internalError == UNKNOWN_ERROR) { // find better error code
4219251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        const status_t omxStatus = statusFromOMXError(error);
4220251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        if (omxStatus != 0) {
4221251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            internalError = omxStatus;
4222251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        } else {
4223251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            ALOGW("Invalid OMX error %#x", error);
4224251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        }
4225251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
42265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("err", internalError);
4227251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    notify->setInt32("actionCode", ACTION_CODE_FATAL); // could translate from OMX error.
4228cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->post();
4229cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber}
4230cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber
4231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4233eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberACodec::PortDescription::PortDescription() {
4234eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
4235eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4236496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t ACodec::requestIDRFrame() {
4237496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    if (!mIsEncoder) {
4238496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        return ERROR_UNSUPPORTED;
4239496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    }
4240496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4241496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    OMX_CONFIG_INTRAREFRESHVOPTYPE params;
4242496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    InitOMXParams(&params);
4243496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4244496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.nPortIndex = kPortIndexOutput;
4245496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.IntraRefreshVOP = OMX_TRUE;
4246496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4247496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    return mOMX->setConfig(
4248496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            mNode,
4249496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            OMX_IndexConfigVideoIntraVOPRefresh,
4250496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            &params,
4251496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            sizeof(params));
4252496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
4253496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4254eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubervoid ACodec::PortDescription::addBuffer(
4255eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        IOMX::buffer_id id, const sp<ABuffer> &buffer) {
4256eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBufferIDs.push_back(id);
4257eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBuffers.push_back(buffer);
4258eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
4259eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4260eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersize_t ACodec::PortDescription::countBuffers() {
4261eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.size();
4262eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
4263eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4264eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberIOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const {
4265eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.itemAt(index);
4266eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
4267eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4268eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const {
4269eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBuffers.itemAt(index);
4270eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
4271eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4272eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber////////////////////////////////////////////////////////////////////////////////
4273eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4274f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
4275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : AState(parentState),
4276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mCodec(codec) {
4277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4279ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas HuberACodec::BaseState::PortMode ACodec::BaseState::getPortMode(
4280ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
4281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return KEEP_BUFFERS;
4282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4284f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
4285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatInputBufferFilled:
4287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onInputBufferFilled(msg);
4289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatOutputBufferDrained:
4293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onOutputBufferDrained(msg);
4295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatOMXMessage:
4299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXMessage(msg);
4301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
43031dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        case ACodec::kWhatSetSurface:
43041dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        {
43051dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            sp<AReplyToken> replyID;
43061dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            CHECK(msg->senderAwaitsResponse(&replyID));
43071dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
43081dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            sp<RefBase> obj;
43091dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            CHECK(msg->findObject("surface", &obj));
43101dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
4311011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            status_t err =
4312011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                ADebug::isExperimentEnabled("legacy-setsurface") ? BAD_VALUE :
4313011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                        mCodec->handleSetSurface(static_cast<Surface *>(obj.get()));
43141dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
43151dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            sp<AMessage> response = new AMessage;
43161dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            response->setInt32("err", err);
43171dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            response->postReply(replyID);
43181dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            break;
43191dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
43201dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
43217cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
43228f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang        case ACodec::kWhatSetInputSurface:
43237cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
43247cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
4325251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            // This may result in an app illegal state exception.
43267cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            ALOGE("Message 0x%x was not handled", msg->what());
43277cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
43287cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            return true;
43297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
43307cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4331ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        case ACodec::kWhatOMXDied:
4332ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        {
4333251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            // This will result in kFlagSawMediaServerDie handling in MediaCodec.
4334ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            ALOGE("OMX/mediaserver died, signalling error!");
4335ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT);
4336ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            break;
4337ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        }
4338ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
433930358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        case ACodec::kWhatReleaseCodecInstance:
434030358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        {
434130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            ALOGI("[%s] forcing the release of codec",
434230358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar                    mCodec->mComponentName.c_str());
434330358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            status_t err = mCodec->mOMX->freeNode(mCodec->mNode);
434430358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            ALOGE_IF("[%s] failed to release codec instance: err=%d",
434530358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar                       mCodec->mComponentName.c_str(), err);
434630358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            sp<AMessage> notify = mCodec->mNotify->dup();
434730358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
434830358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            notify->post();
434930358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            break;
435030358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        }
435130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar
4352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
4354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4359f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
4360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t type;
4361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findInt32("type", &type));
4362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
43635e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // there is a possibility that this is an outstanding message for a
43645e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // codec that we have already destroyed
4365ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    if (mCodec->mNode == 0) {
43665e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar        ALOGI("ignoring message as already freed component: %s",
43675e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar                msg->debugString().c_str());
43685e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar        return true;
43695e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    }
43705e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar
4371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::node_id nodeID;
4372609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("node", (int32_t*)&nodeID));
4373777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (nodeID != mCodec->mNode) {
4374777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("Unexpected message for nodeID: %u, should have been %u", nodeID, mCodec->mNode);
4375777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return false;
4376777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
4377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (type) {
4379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EVENT:
4380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t event, data1, data2;
4382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("event", &event));
4383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data1", &data1));
4384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data2", &data2));
4385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
43860af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            if (event == OMX_EventCmdComplete
43870af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data1 == OMX_CommandFlush
43880af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data2 == (int32_t)OMX_ALL) {
43890af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // Use of this notification is not consistent across
43900af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // implementations. We'll drop this notification and rely
43910af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // on flush-complete notifications on the individual port
43920af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // indices instead.
43930af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
43940af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                return true;
43950af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            }
43960af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
4397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEvent(
4398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_EVENTTYPE>(event),
4399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data1),
4400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data2));
4401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EMPTY_BUFFER_DONE:
4404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
4406609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
4407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEmptyBufferDone(bufferID);
4409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::FILL_BUFFER_DONE:
4412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
4414609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
4415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t rangeOffset, rangeLength, flags;
4417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs;
4418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_offset", &rangeOffset));
4420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_length", &rangeLength));
4421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("flags", &flags));
4422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt64("timestamp", &timeUs));
4423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXFillBufferDone(
4425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    bufferID,
4426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (size_t)rangeOffset, (size_t)rangeLength,
4427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (OMX_U32)flags,
4428784e24e386b088c05d653ab482f2e95cb53e3d01Andy Hung                    timeUs);
4429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4432777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("Unexpected message type: %d", type);
4433777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return false;
4434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4437f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEvent(
4438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (event != OMX_EventError) {
4440ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        ALOGV("[%s] EVENT(%d, 0x%08x, 0x%08x)",
4441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mCodec->mComponentName.c_str(), event, data1, data2);
4442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return false;
4444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4446ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGE("[%s] ERROR(0x%08x)", mCodec->mComponentName.c_str(), data1);
4447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4448251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // verify OMX component sends back an error we expect.
4449251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    OMX_ERRORTYPE omxError = (OMX_ERRORTYPE)data1;
4450251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (!isOMXError(omxError)) {
4451251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        ALOGW("Invalid OMX error %#x", omxError);
4452251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        omxError = OMX_ErrorUndefined;
4453251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
4454251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    mCodec->signalError(omxError);
4455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4459f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID) {
4460ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGV("[%s] onOMXEmptyBufferDone %u",
4461349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber         mCodec->mComponentName.c_str(), bufferID);
4462349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
44630806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
44640806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
44650806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (status != BufferInfo::OWNED_BY_COMPONENT) {
44660806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGE("Wrong ownership in EBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
44670806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->dumpBuffers(kPortIndexInput);
44680806340688c937e7b78c2d89db3809274130df4eLajos Molnar        return false;
44690806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
4470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
4471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
447296e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // We're in "store-metadata-in-buffers" mode, the underlying
447396e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // OMX component had access to data that's implicitly refcounted
447496e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // by this "MediaBuffer" object. Now that the OMX component has
447596e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // told us that it's done with the input buffer, we can decrement
447696e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // the mediaBuffer's reference count.
447796e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    info->mData->setMediaBufferBase(NULL);
4478d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
4480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            postFillThisBuffer(info);
4487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4489777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        case FREE_BUFFERS:
4490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4491777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("SHOULD NOT REACH HERE: cannot free empty output buffers");
4492777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return false;
4493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4498f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
4499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
4500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
4501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
4504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
4506d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatFillThisBuffer);
4507609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    notify->setInt32("buffer-id", info->mBufferID);
4508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mData->meta()->clear();
45102d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    notify->setBuffer("buffer", info->mData);
4511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
45121d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec);
4513609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    reply->setInt32("buffer-id", info->mBufferID);
4514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setMessage("reply", reply);
4516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->post();
4518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
4520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4522f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
4523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
4524609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
45252d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    sp<ABuffer> buffer;
4526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t err = OK;
45275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool eos = false;
4528a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar    PortMode mode = getPortMode(kPortIndexInput);
45295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
45302d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    if (!msg->findBuffer("buffer", &buffer)) {
4531a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar        /* these are unfilled buffers returned by client */
4532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findInt32("err", &err));
4533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
45347fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        if (err == OK) {
45357fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            /* buffers with no errors are returned on MediaCodec.flush */
45367fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            mode = KEEP_BUFFERS;
45377fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        } else {
45387fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            ALOGV("[%s] saw error %d instead of an input buffer",
45397fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                 mCodec->mComponentName.c_str(), err);
45407fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            eos = true;
45417fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        }
45423831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
45432d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber        buffer.clear();
4544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
45465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
45475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
45485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
45495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = ERROR_END_OF_STREAM;
45505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
45515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
45530806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
45540806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (status != BufferInfo::OWNED_BY_UPSTREAM) {
45550806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGE("Wrong ownership in IBF: %s(%d) buffer #%u", _asString(status), status, bufferID);
45560806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->dumpBuffers(kPortIndexInput);
45570806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
45580806340688c937e7b78c2d89db3809274130df4eLajos Molnar        return;
45590806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
4560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
4562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
45665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (eos) {
4567dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (!mCodec->mPortEOS[kPortIndexInput]) {
4568dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
4569dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mInputEOSResult = err;
4570dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
4571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
45775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
4578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int64_t timeUs;
4579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
4580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
4582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t isCSD;
4584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
4585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
4586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
4587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
45885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (eos) {
45895778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    flags |= OMX_BUFFERFLAG_EOS;
45905778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
45915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer != info->mData) {
4593ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] Needs to copy input data for buffer %u. (%p != %p)",
4594d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(),
4595d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         bufferID,
4596d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         buffer.get(), info->mData.get());
4597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
45980806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    if (buffer->size() > info->mData->capacity()) {
45990806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        ALOGE("data size (%zu) is greated than buffer capacity (%zu)",
46000806340688c937e7b78c2d89db3809274130df4eLajos Molnar                                buffer->size(),           // this is the data received
46010806340688c937e7b78c2d89db3809274130df4eLajos Molnar                                info->mData->capacity()); // this is out buffer size
46020806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
46030806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        return;
46040806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    }
4605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    memcpy(info->mData->data(), buffer->data(), buffer->size());
4606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
4607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4608078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
4609ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] calling emptyBuffer %u w/ codec specific data",
4610078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID);
46115778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else if (flags & OMX_BUFFERFLAG_EOS) {
4612ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] calling emptyBuffer %u w/ EOS",
46135778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str(), bufferID);
4614078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                } else {
4615d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
4616ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGI("[%s] calling emptyBuffer %u w/ time %lld us",
4617ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                         mCodec->mComponentName.c_str(), bufferID, (long long)timeUs);
4618d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#else
4619ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] calling emptyBuffer %u w/ time %lld us",
4620ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                         mCodec->mComponentName.c_str(), bufferID, (long long)timeUs);
4621d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
4622078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                }
4623349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4624d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
4625d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ACodec::BufferStats stats;
4626d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
4627d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mFillBufferDoneTimeUs = -1ll;
4628d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mCodec->mBufferStats.add(timeUs, stats);
4629d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
4630d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4631054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                if (mCodec->mStoreMetaDataInOutputBuffers) {
4632054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    // try to submit an output buffer for each input buffer
4633054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    PortMode outputMode = getPortMode(kPortIndexOutput);
4634054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4635054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    ALOGV("MetaDataBuffersToSubmit=%u portMode=%s",
4636054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            mCodec->mMetaDataBuffersToSubmit,
4637054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            (outputMode == FREE_BUFFERS ? "FREE" :
4638054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                             outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
4639054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    if (outputMode == RESUBMIT_BUFFERS) {
4640e53350373ac516257b4f8956ff1e3f1ac48f607eLajos Molnar                        mCodec->submitOutputMetaDataBuffer();
4641054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    }
4642054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                }
46430806340688c937e7b78c2d89db3809274130df4eLajos Molnar                status_t err2 = mCodec->mOMX->emptyBuffer(
46440806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->mNode,
46450806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    bufferID,
46460806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    0,
46470806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    buffer->size(),
46480806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    flags,
46490806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    timeUs);
46500806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err2 != OK) {
46510806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err2));
46520806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    return;
46530806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
4654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
46560806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (!eos && err == OK) {
46575778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    getMoreInputDataIfPossible();
46585778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
46590806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGV("[%s] Signalled EOS (%d) on the input port",
46600806340688c937e7b78c2d89db3809274130df4eLajos Molnar                         mCodec->mComponentName.c_str(), err);
46615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
46625778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
46635778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mInputEOSResult = err;
46645778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
4665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
46660806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err != OK && err != ERROR_END_OF_STREAM) {
46670806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGV("[%s] Signalling EOS on the input port due to error %d",
4668dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str(), err);
4669dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                } else {
46703856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port",
4671dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str());
4672dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
4673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4674ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                ALOGV("[%s] calling emptyBuffer %u signalling EOS",
4675349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                     mCodec->mComponentName.c_str(), bufferID);
4676349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
46770806340688c937e7b78c2d89db3809274130df4eLajos Molnar                status_t err2 = mCodec->mOMX->emptyBuffer(
46780806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        mCodec->mNode,
46790806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        bufferID,
46800806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        0,
46810806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        0,
46820806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        OMX_BUFFERFLAG_EOS,
46830806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        0);
46840806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err2 != OK) {
46850806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err2));
46860806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    return;
46870806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
4688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexInput] = true;
4691dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                mCodec->mInputEOSResult = err;
4692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4695625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih
4696777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        case FREE_BUFFERS:
4697777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            break;
4698777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim
4699625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih        default:
4700777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("invalid port mode: %d", mode);
4701625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih            break;
4702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4705f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::getMoreInputDataIfPossible() {
4706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
4707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
4708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *eligible = NULL;
4711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
4713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
4714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
4716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
4717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // There's already a "read" pending.
4718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
4719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
4721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_US) {
4723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            eligible = info;
4724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (eligible == NULL) {
4728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
4729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(eligible);
4732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4734f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXFillBufferDone(
4735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferID,
4736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        size_t rangeOffset, size_t rangeLength,
4737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 flags,
4738784e24e386b088c05d653ab482f2e95cb53e3d01Andy Hung        int64_t timeUs) {
4739609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] onOMXFillBufferDone %u time %" PRId64 " us, flags = 0x%08x",
47405778822d86b0337407514b9372562b86edfa91cdAndreas Huber         mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
4741349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
47430806340688c937e7b78c2d89db3809274130df4eLajos Molnar    status_t err= OK;
4744d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4745d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
4746d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    index = mCodec->mBufferStats.indexOfKey(timeUs);
4747d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (index >= 0) {
4748d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
4749d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
4750d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4751d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ALOGI("frame PTS %lld: %lld",
4752d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                timeUs,
4753d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
4754d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4755d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mCodec->mBufferStats.removeItemsAt(index);
4756d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats = NULL;
4757d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
4758d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
4759d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
4761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
47620806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
47630806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (status != BufferInfo::OWNED_BY_COMPONENT) {
47640806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGE("Wrong ownership in FBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
47650806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->dumpBuffers(kPortIndexOutput);
47660806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
47670806340688c937e7b78c2d89db3809274130df4eLajos Molnar        return true;
47680806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
4769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4770054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mDequeuedAt = ++mCodec->mDequeueCounter;
4771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
4772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
4774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4775f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4781a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            if (rangeLength == 0 && (!(flags & OMX_BUFFERFLAG_EOS)
4782a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                    || mCodec->mPortEOS[kPortIndexOutput])) {
4783609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                ALOGV("[%s] calling fillBuffer %u",
47845778822d86b0337407514b9372562b86edfa91cdAndreas Huber                     mCodec->mComponentName.c_str(), info->mBufferID);
4785349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
47860806340688c937e7b78c2d89db3809274130df4eLajos Molnar                err = mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID);
47870806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err != OK) {
47880806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
47890806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    return true;
47900806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
4791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
47925778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
47935778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
47945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
479531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4796577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            sp<AMessage> reply =
47971d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar                new AMessage(kWhatOutputBufferDrained, mCodec);
4798577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
47994bdda35319d5f46efea2089b865c8a64816389cdMarco Nelissen            if (!mCodec->mSentFormat && rangeLength > 0) {
4800577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->sendFormatChange(reply);
48015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
4802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4803308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            if (mCodec->mUseMetadataOnEncoderOutput) {
4804308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                native_handle_t* handle =
4805308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        *(native_handle_t**)(info->mData->data() + 4);
4806308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setPointer("handle", handle);
4807308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeOffset", rangeOffset);
4808308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeLength", rangeLength);
4809308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            } else {
4810308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->setRange(rangeOffset, rangeLength);
4811308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            }
4812496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#if 0
481321ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen            if (mCodec->mNativeWindow == NULL) {
4814496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                if (IsIDR(info->mData)) {
4815496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                    ALOGI("IDR frame");
4816496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                }
48175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
481821ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen#endif
4819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
48208b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            if (mCodec->mSkipCutBuffer != NULL) {
48218b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                mCodec->mSkipCutBuffer->submit(info->mData);
48228b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            }
48235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mData->meta()->setInt64("timeUs", timeUs);
4824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
48255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4826d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatDrainThisBuffer);
4827609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            notify->setInt32("buffer-id", info->mBufferID);
48282d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            notify->setBuffer("buffer", info->mData);
48295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("flags", flags);
4830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4831609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            reply->setInt32("buffer-id", info->mBufferID);
4832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
48335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setMessage("reply", reply);
4834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
48355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->post();
48365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
48375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
4838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (flags & OMX_BUFFERFLAG_EOS) {
48405778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
48415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                sp<AMessage> notify = mCodec->mNotify->dup();
4843d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar                notify->setInt32("what", CodecBase::kWhatEOS);
4844dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                notify->setInt32("err", mCodec->mInputEOSResult);
4845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->post();
4846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexOutput] = true;
4848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4850f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4852777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        case FREE_BUFFERS:
48530806340688c937e7b78c2d89db3809274130df4eLajos Molnar            err = mCodec->freeBuffer(kPortIndexOutput, index);
48540806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
48550806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
48560806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
48570806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
4858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4859777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim
4860777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        default:
4861777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("Invalid port mode: %d", mode);
4862777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return false;
4863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4868f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
4869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
4870609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
4871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
48720806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo *info = mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
48730806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
48740806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (status != BufferInfo::OWNED_BY_DOWNSTREAM) {
48750806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGE("Wrong ownership in OBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
48760806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->dumpBuffers(kPortIndexOutput);
48770806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
48780806340688c937e7b78c2d89db3809274130df4eLajos Molnar        return;
48790806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
4880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4881577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    android_native_rect_t crop;
4882777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (msg->findRect("crop", &crop.left, &crop.top, &crop.right, &crop.bottom)) {
4883777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        status_t err = native_window_set_crop(mCodec->mNativeWindow.get(), &crop);
4884777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGW_IF(err != NO_ERROR, "failed to set crop: %d", err);
4885577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    }
4886577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
4887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t render;
4888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mNativeWindow != NULL
48896aade6058521b0dbd35a9a4620f4d04f02f90444Marco Nelissen            && msg->findInt32("render", &render) && render != 0
489079ee2399b67c7a11042c5904dc1309712a76f8cbJianzheng Zhou            && info->mData != NULL && info->mData->size() != 0) {
48916fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        ATRACE_NAME("render");
4892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The client wants this buffer to be rendered.
4893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4894fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        int64_t timestampNs = 0;
4895fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        if (!msg->findInt64("timestampNs", &timestampNs)) {
4896fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // TODO: it seems like we should use the timestamp
4897fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // in the (media)buffer as it potentially came from
4898fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // an input surface, but we did not propagate it prior to
4899fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // API 20.  Perhaps check for target SDK version.
4900fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#if 0
4901fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            if (info->mData->meta()->findInt64("timeUs", &timestampNs)) {
490247aea1f7c58f5302b16822f9e7e1763f2af04ef5Lajos Molnar                ALOGV("using buffer PTS of %" PRId64, timestampNs);
4903fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar                timestampNs *= 1000;
4904fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            }
4905fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#endif
4906fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
4907fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
49085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err;
4909fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        err = native_window_set_buffers_timestamp(mCodec->mNativeWindow.get(), timestampNs);
49100806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGW_IF(err != NO_ERROR, "failed to set buffer timestamp: %d", err);
4911fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
49120806340688c937e7b78c2d89db3809274130df4eLajos Molnar        err = mCodec->mNativeWindow->queueBuffer(
49130806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->mNativeWindow.get(), info->mGraphicBuffer.get(), -1);
49140806340688c937e7b78c2d89db3809274130df4eLajos Molnar        if (err == OK) {
4915cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
4916cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        } else {
4917251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
4918cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
4919cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        }
4920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
49216fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        if (mCodec->mNativeWindow != NULL &&
49226fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar            (info->mData == NULL || info->mData->size() != 0)) {
49236fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar            ATRACE_NAME("frame-drop");
49246fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        }
4925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_US;
4926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
4929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
4934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // We cannot resubmit the buffer we just rendered, dequeue
4937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // the spare instead.
4938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info = mCodec->dequeueBufferFromNativeWindow();
4940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (!mCodec->mPortEOS[kPortIndexOutput]) {
4947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // We cannot resubmit the buffer we just rendered, dequeue
4949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // the spare instead.
4950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info = mCodec->dequeueBufferFromNativeWindow();
4952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
4953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4954c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                if (info != NULL) {
4955609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                    ALOGV("[%s] calling fillBuffer %u",
4956c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                         mCodec->mComponentName.c_str(), info->mBufferID);
49570806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    status_t err = mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID);
49580806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    if (err == OK) {
49590806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
49600806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    } else {
49610806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
49620806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    }
4963c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                }
4964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4968777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        case FREE_BUFFERS:
4969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
49700806340688c937e7b78c2d89db3809274130df4eLajos Molnar            status_t err = mCodec->freeBuffer(kPortIndexOutput, index);
49710806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
49720806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
49730806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
4974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4976777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim
4977777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        default:
4978777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("Invalid port mode: %d", mode);
4979777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return;
4980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4985f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::UninitializedState::UninitializedState(ACodec *codec)
4986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4989c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::UninitializedState::stateEntered() {
4990c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("Now uninitialized");
4991ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4992ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (mDeathNotifier != NULL) {
4993f888020c6e2735624f2b2a30e72aca24e17b8b4dMarco Nelissen        IInterface::asBinder(mCodec->mOMX)->unlinkToDeath(mDeathNotifier);
4994ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
4995ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
4996ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4997ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNativeWindow.clear();
4998ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    mCodec->mNode = 0;
4999ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mOMX.clear();
5000ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mQuirks = 0;
5001ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mFlags = 0;
5002308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    mCodec->mUseMetadataOnEncoderOutput = 0;
5003ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mComponentName.clear();
5004c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
5005c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5006f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
5007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatSetup:
5011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onSetup(msg);
5013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
50185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case ACodec::kWhatAllocateComponent:
50195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
50205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            onAllocateComponent(msg);
50215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            handled = true;
50225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
50235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
50245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatShutdown:
5026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5027c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
5028c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
5029c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
503054b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            ALOGW_IF(keepComponentAllocated,
503154b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar                     "cannot keep component allocated on shutdown in Uninitialized state");
5032c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
5034d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
5035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
5036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5038c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
5039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatFlush:
5042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
5044d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
5045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
5046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5048c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
5049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
505130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        case ACodec::kWhatReleaseCodecInstance:
505230358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        {
505330358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            // nothing to do, as we have already signaled shutdown
505430358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            handled = true;
505530358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            break;
505630358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        }
505730358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar
5058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
5060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5065f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::UninitializedState::onSetup(
5066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
5067c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (onAllocateComponent(msg)
5068c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            && mCodec->mLoadedState->onConfigureComponent(msg)) {
5069c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mLoadedState->onStart();
5070c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
50715778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
50725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5073c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
50745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onAllocateComponent");
50755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5076ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    CHECK(mCodec->mNode == 0);
50775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMXClient client;
507948a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung    if (client.connect() != OK) {
508048a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung        mCodec->signalError(OMX_ErrorUndefined, NO_INIT);
508148a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung        return false;
508248a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung    }
5083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<IOMX> omx = client.interface();
5085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
50861d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec);
5087ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
5088ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mDeathNotifier = new DeathNotifier(notify);
5089f888020c6e2735624f2b2a30e72aca24e17b8b4dMarco Nelissen    if (IInterface::asBinder(omx)->linkToDeath(mDeathNotifier) != OK) {
5090ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // This was a local binder, if it dies so do we, we won't care
5091ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // about any notifications in the afterlife.
5092ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
5093ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
5094ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
5095e671207115fac3914134c61b336d5fa0242c68caAndreas Huber    Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs;
50965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    AString mime;
5098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
50995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString componentName;
5100d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint32_t quirks = 0;
51017791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen    int32_t encoder = false;
51025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findString("componentName", &componentName)) {
5103e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        ssize_t index = matchingCodecs.add();
5104e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        OMXCodec::CodecNameAndQuirks *entry = &matchingCodecs.editItemAt(index);
5105e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        entry->mName = String8(componentName.c_str());
5106afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
5107e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        if (!OMXCodec::findCodecQuirks(
5108e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                    componentName.c_str(), &entry->mQuirks)) {
5109e671207115fac3914134c61b336d5fa0242c68caAndreas Huber            entry->mQuirks = 0;
5110afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
51115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
51125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(msg->findString("mime", &mime));
51135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
51145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("encoder", &encoder)) {
51155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder = false;
51165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
51175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
51185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMXCodec::findMatchingCodecs(
51195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mime.c_str(),
51205778822d86b0337407514b9372562b86edfa91cdAndreas Huber                encoder, // createEncoder
51215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                NULL,  // matchComponentName
51225778822d86b0337407514b9372562b86edfa91cdAndreas Huber                0,     // flags
5123e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                &matchingCodecs);
51245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
51251065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
51261065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    sp<CodecObserver> observer = new CodecObserver;
5127ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    IOMX::node_id node = 0;
51281065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
5129201d8d400eb037547f4f476a838475b13a446007Wei Jia    status_t err = NAME_NOT_FOUND;
51301065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
51311065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            ++matchIndex) {
5132e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        componentName = matchingCodecs.itemAt(matchIndex).mName.string();
5133e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        quirks = matchingCodecs.itemAt(matchIndex).mQuirks;
5134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5135da153975581fb3161a30452348a5b26ee72d9255Elliott Hughes        pid_t tid = gettid();
5136078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        int prevPriority = androidGetThreadPriority(tid);
5137078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
51389f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu        err = omx->allocateNode(componentName.c_str(), observer, &node);
5139078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, prevPriority);
5140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
51411065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        if (err == OK) {
51421065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            break;
51437a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He        } else {
51447a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He            ALOGW("Allocating component '%s' failed, try next one.", componentName.c_str());
51451065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
51461065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
5147ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        node = 0;
51481065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    }
51491065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
5150ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    if (node == 0) {
51515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!mime.empty()) {
51529f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu            ALOGE("Unable to instantiate a %scoder for type '%s' with err %#x.",
51539f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu                    encoder ? "en" : "de", mime.c_str(), err);
51545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
51559f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu            ALOGE("Unable to instantiate codec '%s' with err %#x.", componentName.c_str(), err);
51565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
5157c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
515852e88b2986536e83a7a6da63461556b8734a85f3Ronghua Wu        mCodec->signalError((OMX_ERRORTYPE)err, makeNoSideEffectStatus(err));
5159c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
5160c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
5161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
51621d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    notify = new AMessage(kWhatOMXMessage, mCodec);
5163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    observer->setNotificationMessage(notify);
5164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mComponentName = componentName;
5166ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    mCodec->mFlags = 0;
5167ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
5168ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (componentName.endsWith(".secure")) {
5169ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        mCodec->mFlags |= kFlagIsSecure;
51701713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        mCodec->mFlags |= kFlagIsGrallocUsageProtected;
51710167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
5172ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
5173ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
5174afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mCodec->mQuirks = quirks;
5175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mOMX = omx;
5176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mNode = node;
5177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
51785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
51795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
5180d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatComponentAllocated);
51815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setString("componentName", mCodec->mComponentName.c_str());
51825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
51835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5184c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5185c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mCodec->changeState(mCodec->mLoadedState);
5186c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5187c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
51885778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
51895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5190c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
5191c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5192c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas HuberACodec::LoadedState::LoadedState(ACodec *codec)
5193c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    : BaseState(codec) {
5194c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
5195c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5196c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::stateEntered() {
5197c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
5198c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5199f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mPortEOS[kPortIndexInput] =
5200f6f38287b97ec69b169387add6458f859b770e65Andreas Huber        mCodec->mPortEOS[kPortIndexOutput] = false;
5201f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
5202f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mInputEOSResult = OK;
5203f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
5204054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mDequeueCounter = 0;
5205054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mMetaDataBuffersToSubmit = 0;
5206a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    mCodec->mRepeatFrameDelayUs = -1ll;
5207e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mInputFormat.clear();
5208e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mOutputFormat.clear();
52094e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    mCodec->mBaseOutputFormat.clear();
5210054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5211c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (mCodec->mShutdownInProgress) {
5212c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
5213c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5214c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mShutdownInProgress = false;
5215c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mKeepComponentAllocated = false;
5216c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5217c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        onShutdown(keepComponentAllocated);
5218c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
521954b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    mCodec->mExplicitShutdown = false;
5220f393c33e65ae51a7cf168b4e15771b152f996b32Wei Jia
5221f393c33e65ae51a7cf168b4e15771b152f996b32Wei Jia    mCodec->processDeferredMessages();
5222c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
5223c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5224c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
5225c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (!keepComponentAllocated) {
52260806340688c937e7b78c2d89db3809274130df4eLajos Molnar        (void)mCodec->mOMX->freeNode(mCodec->mNode);
5227c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5228c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->changeState(mCodec->mUninitializedState);
5229c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
5230c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
523154b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    if (mCodec->mExplicitShutdown) {
523254b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        sp<AMessage> notify = mCodec->mNotify->dup();
5233d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
523454b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        notify->post();
523554b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        mCodec->mExplicitShutdown = false;
523654b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    }
5237c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
5238c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5239c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
5240c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool handled = false;
5241c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5242c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    switch (msg->what()) {
5243c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatConfigureComponent:
5244c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
5245c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onConfigureComponent(msg);
5246c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
5247c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
5248c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
5249c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
52507cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
52517cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
52527cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            onCreateInputSurface(msg);
52537cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
52547cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
52557cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
52567cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
52578f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang        case ACodec::kWhatSetInputSurface:
5258d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        {
52598f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang            onSetInputSurface(msg);
5260d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            handled = true;
5261d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            break;
5262d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        }
5263d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5264c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatStart:
5265c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
5266c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onStart();
5267c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
5268c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
5269c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
5270c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5271c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatShutdown:
5272c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
5273c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
5274c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
5275c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
5276c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
527754b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
5278c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onShutdown(keepComponentAllocated);
5279c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5280c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
5281c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
5282c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
5283c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5284c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatFlush:
5285c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
5286c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
5287d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
5288c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->post();
5289c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5290c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
5291c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
5292c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
5293c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5294c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        default:
5295c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            return BaseState::onMessageReceived(msg);
5296c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
5297c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5298c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return handled;
5299c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
5300c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5301c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onConfigureComponent(
53025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg) {
53035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onConfigureComponent");
53045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5305ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    CHECK(mCodec->mNode != 0);
53065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
53070806340688c937e7b78c2d89db3809274130df4eLajos Molnar    status_t err = OK;
53085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString mime;
53090806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (!msg->findString("mime", &mime)) {
53100806340688c937e7b78c2d89db3809274130df4eLajos Molnar        err = BAD_VALUE;
53110806340688c937e7b78c2d89db3809274130df4eLajos Molnar    } else {
53120806340688c937e7b78c2d89db3809274130df4eLajos Molnar        err = mCodec->configureCodec(mime.c_str(), msg);
53130806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
53145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
5315c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        ALOGE("[%s] configureCodec returning error %d",
5316c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber              mCodec->mComponentName.c_str(), err);
5317c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber
5318251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5319c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
53205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
53225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
53235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
5324d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatComponentConfigured);
5325e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("input-format", mCodec->mInputFormat);
5326e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("output-format", mCodec->mOutputFormat);
53275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
53285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5329c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5330c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
53315778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
53325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5333d291c222357303b9611cab89d0c3b047584ef377Chong Zhangstatus_t ACodec::LoadedState::setupInputSurface() {
5334d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    status_t err = OK;
5335a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
5336d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mRepeatFrameDelayUs > 0ll) {
5337a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        err = mCodec->mOMX->setInternalOption(
5338a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                mCodec->mNode,
5339a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                kPortIndexInput,
5340a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY,
5341a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                &mCodec->mRepeatFrameDelayUs,
5342a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                sizeof(mCodec->mRepeatFrameDelayUs));
5343a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
5344a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (err != OK) {
5345a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            ALOGE("[%s] Unable to configure option to repeat previous "
5346a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  "frames (err %d)",
5347a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  mCodec->mComponentName.c_str(),
5348a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  err);
5349d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
5350a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
5351a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
5352a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
5353d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mMaxPtsGapUs > 0ll) {
535494ee4b708acfa941581160b267afb79192b1d816Chong Zhang        err = mCodec->mOMX->setInternalOption(
535594ee4b708acfa941581160b267afb79192b1d816Chong Zhang                mCodec->mNode,
535694ee4b708acfa941581160b267afb79192b1d816Chong Zhang                kPortIndexInput,
535794ee4b708acfa941581160b267afb79192b1d816Chong Zhang                IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP,
535894ee4b708acfa941581160b267afb79192b1d816Chong Zhang                &mCodec->mMaxPtsGapUs,
535994ee4b708acfa941581160b267afb79192b1d816Chong Zhang                sizeof(mCodec->mMaxPtsGapUs));
536094ee4b708acfa941581160b267afb79192b1d816Chong Zhang
536194ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (err != OK) {
536294ee4b708acfa941581160b267afb79192b1d816Chong Zhang            ALOGE("[%s] Unable to configure max timestamp gap (err %d)",
536372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    mCodec->mComponentName.c_str(),
536472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    err);
5365d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
53662c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
53672c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
53682c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
5369d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mMaxFps > 0) {
537037b2b389139ed638831e49708c947863eef631efRonghua Wu        err = mCodec->mOMX->setInternalOption(
537137b2b389139ed638831e49708c947863eef631efRonghua Wu                mCodec->mNode,
537237b2b389139ed638831e49708c947863eef631efRonghua Wu                kPortIndexInput,
537337b2b389139ed638831e49708c947863eef631efRonghua Wu                IOMX::INTERNAL_OPTION_MAX_FPS,
537437b2b389139ed638831e49708c947863eef631efRonghua Wu                &mCodec->mMaxFps,
537537b2b389139ed638831e49708c947863eef631efRonghua Wu                sizeof(mCodec->mMaxFps));
537637b2b389139ed638831e49708c947863eef631efRonghua Wu
537737b2b389139ed638831e49708c947863eef631efRonghua Wu        if (err != OK) {
537837b2b389139ed638831e49708c947863eef631efRonghua Wu            ALOGE("[%s] Unable to configure max fps (err %d)",
537937b2b389139ed638831e49708c947863eef631efRonghua Wu                    mCodec->mComponentName.c_str(),
538037b2b389139ed638831e49708c947863eef631efRonghua Wu                    err);
5381d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
538237b2b389139ed638831e49708c947863eef631efRonghua Wu        }
538337b2b389139ed638831e49708c947863eef631efRonghua Wu    }
538437b2b389139ed638831e49708c947863eef631efRonghua Wu
5385d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mTimePerCaptureUs > 0ll
53862c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            && mCodec->mTimePerFrameUs > 0ll) {
53872c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        int64_t timeLapse[2];
53882c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[0] = mCodec->mTimePerFrameUs;
53892c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[1] = mCodec->mTimePerCaptureUs;
53902c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        err = mCodec->mOMX->setInternalOption(
53912c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                mCodec->mNode,
53922c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                kPortIndexInput,
53932c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                IOMX::INTERNAL_OPTION_TIME_LAPSE,
53942c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                &timeLapse[0],
53952c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                sizeof(timeLapse));
53962c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
53972c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (err != OK) {
53982c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            ALOGE("[%s] Unable to configure time lapse (err %d)",
53992c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    mCodec->mComponentName.c_str(),
54002c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    err);
5401d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
54022c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
54032c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
540472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
5405d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mCreateInputBuffersSuspended) {
540672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        bool suspend = true;
540772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        err = mCodec->mOMX->setInternalOption(
540872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                mCodec->mNode,
540972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                kPortIndexInput,
541072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                IOMX::INTERNAL_OPTION_SUSPEND,
541172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                &suspend,
541272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                sizeof(suspend));
541372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
541472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
541572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("[%s] Unable to configure option to suspend (err %d)",
541694ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  mCodec->mComponentName.c_str(),
541794ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  err);
5418d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
541994ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
542094ee4b708acfa941581160b267afb79192b1d816Chong Zhang    }
542194ee4b708acfa941581160b267afb79192b1d816Chong Zhang
5422d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    return OK;
5423d291c222357303b9611cab89d0c3b047584ef377Chong Zhang}
5424d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5425d291c222357303b9611cab89d0c3b047584ef377Chong Zhangvoid ACodec::LoadedState::onCreateInputSurface(
5426d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        const sp<AMessage> & /* msg */) {
5427d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    ALOGV("onCreateInputSurface");
5428d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5429d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<AMessage> notify = mCodec->mNotify->dup();
5430d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    notify->setInt32("what", CodecBase::kWhatInputSurfaceCreated);
5431d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5432d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<IGraphicBufferProducer> bufferProducer;
5433d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    status_t err = mCodec->mOMX->createInputSurface(
5434d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            mCodec->mNode, kPortIndexInput, &bufferProducer);
5435d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5436d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (err == OK) {
5437d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        err = setupInputSurface();
5438d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    }
5439d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
54407cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err == OK) {
54417cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setObject("input-surface",
54427cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                new BufferProducerWrapper(bufferProducer));
54437cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else {
54447cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // Can't use mCodec->signalError() here -- MediaCodec won't forward
54457cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // the error through because it's in the "configured" state.  We
54467cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // send a kWhatInputSurfaceCreated with an error value instead.
54477cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGE("[%s] onCreateInputSurface returning error %d",
54487cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                mCodec->mComponentName.c_str(), err);
54497cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setInt32("err", err);
54507cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
54517cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->post();
54527cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
54537cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
54548f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhangvoid ACodec::LoadedState::onSetInputSurface(
5455d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        const sp<AMessage> &msg) {
54568f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang    ALOGV("onSetInputSurface");
5457d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5458d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<AMessage> notify = mCodec->mNotify->dup();
5459d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    notify->setInt32("what", CodecBase::kWhatInputSurfaceAccepted);
5460d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5461d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<RefBase> obj;
5462d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    CHECK(msg->findObject("input-surface", &obj));
5463d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<PersistentSurface> surface = static_cast<PersistentSurface *>(obj.get());
5464d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
54658f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang    status_t err = mCodec->mOMX->setInputSurface(
5466d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            mCodec->mNode, kPortIndexInput, surface->getBufferConsumer());
5467d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5468d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (err == OK) {
5469d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        err = setupInputSurface();
5470d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    }
5471d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5472d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (err != OK) {
5473d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        // Can't use mCodec->signalError() here -- MediaCodec won't forward
5474d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        // the error through because it's in the "configured" state.  We
5475d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        // send a kWhatInputSurfaceAccepted with an error value instead.
54768f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang        ALOGE("[%s] onSetInputSurface returning error %d",
5477d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                mCodec->mComponentName.c_str(), err);
5478d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        notify->setInt32("err", err);
5479d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    }
5480d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    notify->post();
5481d291c222357303b9611cab89d0c3b047584ef377Chong Zhang}
5482d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5483c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onStart() {
54845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onStart");
54855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
54860806340688c937e7b78c2d89db3809274130df4eLajos Molnar    status_t err = mCodec->mOMX->sendCommand(mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle);
54870806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (err != OK) {
54880806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
54890806340688c937e7b78c2d89db3809274130df4eLajos Molnar    } else {
54900806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->changeState(mCodec->mLoadedToIdleState);
54910806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
5492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5496f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
5497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5500f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::LoadedToIdleState::stateEntered() {
55013856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
5502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5503cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    status_t err;
5504cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    if ((err = allocateBuffers()) != OK) {
550529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to allocate buffers after transitioning to IDLE state "
5506cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             "(error 0x%08x)",
5507cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             err);
5508cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
5509251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
551091bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber
551191bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber        mCodec->changeState(mCodec->mLoadedState);
5512cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    }
5513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5515f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::LoadedToIdleState::allocateBuffers() {
5516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
5517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
5519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
5520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mCodec->allocateBuffersOnPort(kPortIndexOutput);
5523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5525f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
5526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
552772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
5528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
5531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
55346507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
55356507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
55366507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
55376507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
55386507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
55396507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
55406463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatResume:
55416463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
55426463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We'll be active soon enough.
55436463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
55446463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
55456463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
55466463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatFlush:
55476463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
55486463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We haven't even started yet, so we're flushed alright...
55496463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            sp<AMessage> notify = mCodec->mNotify->dup();
5550d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
55516463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->post();
55526463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
55536463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
55546463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
5555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
5557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5560f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onOMXEvent(
5561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
55650806340688c937e7b78c2d89db3809274130df4eLajos Molnar            status_t err = OK;
55660806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandStateSet
55670806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    || data2 != (OMX_U32)OMX_StateIdle) {
55680806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("Unexpected command completion in LoadedToIdleState: %s(%u) %s(%u)",
55690806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1,
55700806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_STATETYPE)data2), data2);
55710806340688c937e7b78c2d89db3809274130df4eLajos Molnar                err = FAILED_TRANSACTION;
55720806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
5573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
55740806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err == OK) {
55750806340688c937e7b78c2d89db3809274130df4eLajos Molnar                err = mCodec->mOMX->sendCommand(
55760806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting);
55770806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
5578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
55790806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
55800806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
55810806340688c937e7b78c2d89db3809274130df4eLajos Molnar            } else {
55820806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->changeState(mCodec->mIdleToExecutingState);
55830806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
5584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5595f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
5596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5599f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToExecutingState::stateEntered() {
56003856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
5601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5603f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
5604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
560572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
5606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
5609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5612d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatResume:
5613d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
5614d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We'll be active soon enough.
5615d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
5616d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
5617d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
5618d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatFlush:
5619d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
5620d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We haven't even started yet, so we're flushed alright...
5621d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
5622d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
5623d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->post();
5624d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
5625d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
5626d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
5627d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
56286507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
56296507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
56306507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
56316507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
56326507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
56336507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
5634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
5636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5639f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onOMXEvent(
5640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
56440806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandStateSet
56450806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    || data2 != (OMX_U32)OMX_StateExecuting) {
56460806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("Unexpected command completion in IdleToExecutingState: %s(%u) %s(%u)",
56470806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1,
56480806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_STATETYPE)data2), data2);
56490806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
56500806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
56510806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
5652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mExecutingState->resume();
5654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingState);
5655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5666f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingState::ExecutingState(ACodec *codec)
5667349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    : BaseState(codec),
5668349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber      mActive(false) {
5669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5671f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
5672ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
5673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
5674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5676054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputMetaBuffers() {
5677054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // submit as many buffers as there are input buffers with the codec
5678054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // in case we are in port reconfiguring
5679054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
5680054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
5681054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5682054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) {
5683054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            if (mCodec->submitOutputMetaDataBuffer() != OK)
5684054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                break;
5685054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
5686054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
56874dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
56884dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
56894dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
5690054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
5691054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5692054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitRegularOutputBuffers() {
56930806340688c937e7b78c2d89db3809274130df4eLajos Molnar    bool failed = false;
5694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
5695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
5696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mCodec->mNativeWindow != NULL) {
56980806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (info->mStatus != BufferInfo::OWNED_BY_US
56990806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
57000806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("buffers should be owned by us or the surface");
57010806340688c937e7b78c2d89db3809274130df4eLajos Molnar                failed = true;
57020806340688c937e7b78c2d89db3809274130df4eLajos Molnar                break;
57030806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
5704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
5706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                continue;
5707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
57090806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (info->mStatus != BufferInfo::OWNED_BY_US) {
57100806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("buffers should be owned by us");
57110806340688c937e7b78c2d89db3809274130df4eLajos Molnar                failed = true;
57120806340688c937e7b78c2d89db3809274130df4eLajos Molnar                break;
57130806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
5714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
57160806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGV("[%s] calling fillBuffer %u", mCodec->mComponentName.c_str(), info->mBufferID);
5717349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
57180806340688c937e7b78c2d89db3809274130df4eLajos Molnar        status_t err = mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID);
57190806340688c937e7b78c2d89db3809274130df4eLajos Molnar        if (err != OK) {
57200806340688c937e7b78c2d89db3809274130df4eLajos Molnar            failed = true;
57210806340688c937e7b78c2d89db3809274130df4eLajos Molnar            break;
57220806340688c937e7b78c2d89db3809274130df4eLajos Molnar        }
5723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
5725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
57260806340688c937e7b78c2d89db3809274130df4eLajos Molnar
57270806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (failed) {
57280806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
57290806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
5730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5732054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputBuffers() {
5733c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar    submitRegularOutputBuffers();
5734054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mCodec->mStoreMetaDataInOutputBuffers) {
5735054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        submitOutputMetaBuffers();
5736054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
5737054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
5738054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5739f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::resume() {
5740349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    if (mActive) {
57410806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGV("[%s] We're already active, no need to resume.", mCodec->mComponentName.c_str());
5742349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        return;
5743349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    }
5744349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    submitOutputBuffers();
5746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
57473cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    // Post all available input buffers
5748777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (mCodec->mBuffers[kPortIndexInput].size() == 0u) {
5749777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGW("[%s] we don't have any input buffers to resume", mCodec->mComponentName.c_str());
5750777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
5751777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim
57523cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); i++) {
57533cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
57543cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_US) {
57553cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar            postFillThisBuffer(info);
57563cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        }
57573cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    }
5758349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5759349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    mActive = true;
5760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5762f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::stateEntered() {
57633856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
5764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->processDeferredMessages();
5766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5768f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
5769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5774c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
5775c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
5776c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
5777c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5778c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mShutdownInProgress = true;
577954b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
5780c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mKeepComponentAllocated = keepComponentAllocated;
5781c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5782349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
5783349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
57840806340688c937e7b78c2d89db3809274130df4eLajos Molnar            status_t err = mCodec->mOMX->sendCommand(
57850806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle);
57860806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
57870806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (keepComponentAllocated) {
57880806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
57890806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
57900806340688c937e7b78c2d89db3809274130df4eLajos Molnar                // TODO: do some recovery here.
57910806340688c937e7b78c2d89db3809274130df4eLajos Molnar            } else {
57920806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->changeState(mCodec->mExecutingToIdleState);
57930806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
5794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
58017a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong            ALOGV("[%s] ExecutingState flushing now "
5802ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                 "(codec owns %zu/%zu input, %zu/%zu output).",
5803d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mComponentName.c_str(),
5804d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
5805d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexInput].size(),
5806d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
5807d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexOutput].size());
5808d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
5809349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
5810349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
58110806340688c937e7b78c2d89db3809274130df4eLajos Molnar            status_t err = mCodec->mOMX->sendCommand(mCodec->mNode, OMX_CommandFlush, OMX_ALL);
58120806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
58130806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
58140806340688c937e7b78c2d89db3809274130df4eLajos Molnar            } else {
58150806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->changeState(mCodec->mFlushingState);
58160806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
5817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatResume:
5823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            resume();
5825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5830496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
5831496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
5832496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            status_t err = mCodec->requestIDRFrame();
5833496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            if (err != OK) {
5834496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                ALOGW("Requesting an IDR frame failed.");
5835496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            }
5836496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5837496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            handled = true;
5838496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
5839496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
5840496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5841a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
5842a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
5843a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
5844a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
5845a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5846a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = mCodec->setParameters(params);
5847a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5848a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> reply;
5849a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            if (msg->findMessage("reply", &reply)) {
5850a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->setInt32("err", err);
5851a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->post();
5852a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            }
5853a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5854a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            handled = true;
5855a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
5856a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
5857a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
58587cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
58597cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
58606507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
58617cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
58627cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
58637cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
58647cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
58654dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
58664dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        case kWhatSubmitOutputMetaDataBufferIfEOS:
58674dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        {
58684dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            if (mCodec->mPortEOS[kPortIndexInput] &&
58694dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    !mCodec->mPortEOS[kPortIndexOutput]) {
58704dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                status_t err = mCodec->submitOutputMetaDataBuffer();
58714dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                if (err == OK) {
58724dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
58734dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                }
58744dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            }
58754dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            return true;
58764dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        }
58774dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
5878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5886a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t ACodec::setParameters(const sp<AMessage> &params) {
5887a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    int32_t videoBitrate;
5888530fdbdc1b5491f3fbf172752834d1515701e142Lajos Molnar    if (params->findInt32("video-bitrate", &videoBitrate)) {
5889a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        OMX_VIDEO_CONFIG_BITRATETYPE configParams;
5890a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        InitOMXParams(&configParams);
5891a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nPortIndex = kPortIndexOutput;
5892a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nEncodeBitrate = videoBitrate;
5893a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5894a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        status_t err = mOMX->setConfig(
5895a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                mNode,
5896a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                OMX_IndexConfigVideoBitrate,
5897a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                &configParams,
5898a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                sizeof(configParams));
5899a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5900a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        if (err != OK) {
5901a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
5902a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                   videoBitrate, err);
5903a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5904a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            return err;
5905a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
5906a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    }
5907a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
590872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    int64_t skipFramesBeforeUs;
590972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (params->findInt64("skip-frames-before", &skipFramesBeforeUs)) {
591072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        status_t err =
591172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mOMX->setInternalOption(
591272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     mNode,
591372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     kPortIndexInput,
591472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     IOMX::INTERNAL_OPTION_START_TIME,
591572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     &skipFramesBeforeUs,
591672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     sizeof(skipFramesBeforeUs));
591772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
591872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
591972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("Failed to set parameter 'skip-frames-before' (err %d)", err);
592072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            return err;
592172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
592272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
592372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
5924e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    int32_t dropInputFrames;
5925e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    if (params->findInt32("drop-input-frames", &dropInputFrames)) {
5926e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        bool suspend = dropInputFrames != 0;
5927e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
5928b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err =
5929b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            mOMX->setInternalOption(
5930e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     mNode,
5931e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     kPortIndexInput,
5932e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     IOMX::INTERNAL_OPTION_SUSPEND,
5933e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     &suspend,
5934b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber                     sizeof(suspend));
5935b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
5936b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
5937b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err);
5938b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
5939b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
5940b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    }
5941b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
5942b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    int32_t dummy;
5943b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    if (params->findInt32("request-sync", &dummy)) {
5944b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err = requestIDRFrame();
5945b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
5946b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
5947b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Requesting a sync frame failed w/ err %d", err);
5948b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
5949b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
5950e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    }
5951e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
59528db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    float rate;
59538db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    if (params->findFloat("operating-rate", &rate) && rate > 0) {
59548db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        status_t err = setOperatingRate(rate, mIsVideo);
59558db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        if (err != OK) {
59568db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu            ALOGE("Failed to set parameter 'operating-rate' (err %d)", err);
59578db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu            return err;
59588db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        }
59598db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    }
59608db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu
5961a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return OK;
5962a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
5963a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
59646507d14c6d10f93d390de62b9eed267f9b544985Andy McFaddenvoid ACodec::onSignalEndOfInputStream() {
59656507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    sp<AMessage> notify = mNotify->dup();
5966d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatSignaledInputEOS);
59676507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
59686507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    status_t err = mOMX->signalEndOfInputStream(mNode);
59696507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    if (err != OK) {
59706507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        notify->setInt32("err", err);
59716507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    }
59726507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->post();
59736507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden}
59746507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
5975f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onOMXEvent(
5976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventPortSettingsChanged:
5979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
5981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
598231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
5983054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mCodec->mMetaDataBuffersToSubmit = 0;
5984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
5985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
5986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_CommandPortDisable, kPortIndexOutput),
5987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
5988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5989349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                mCodec->freeOutputBuffersNotOwnedByComponent();
5990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
599231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            } else if (data2 == OMX_IndexConfigCommonOutputCrop) {
599331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
5994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
5995ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08x",
5996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->mComponentName.c_str(), data2);
5997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventBufferFlag:
6003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
6009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
6013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6014f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
6015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ACodec *codec)
6016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
6017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6019f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
6020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
6021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput) {
6022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return FREE_BUFFERS;
6023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
6026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
6028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6030f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onMessageReceived(
6031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
6032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
6033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
6035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
6036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
6037349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case kWhatResume:
6038e6eea3a6b6e0cf92287ec1ceb8350f201d17e1acPer Persson        case kWhatSetParameters:
6039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6040349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            if (msg->what() == kWhatResume) {
60413856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
6042349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            }
6043349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
6045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
6051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
6055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6057f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::OutputPortSettingsChangedState::stateEntered() {
60583856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now handling output port settings change",
6059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mCodec->mComponentName.c_str());
6060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6062f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onOMXEvent(
6063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
6065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
6066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
60680806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (data2 != (OMX_U32)kPortIndexOutput) {
60690806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGW("ignoring EventCmdComplete CommandPortDisable for port %u", data2);
60700806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    return false;
60710806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
6072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
60730806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGV("[%s] Output port now disabled.", mCodec->mComponentName.c_str());
6074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
60750806340688c937e7b78c2d89db3809274130df4eLajos Molnar                status_t err = OK;
60760806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (!mCodec->mBuffers[kPortIndexOutput].isEmpty()) {
60770806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGE("disabled port should be empty, but has %zu buffers",
60780806340688c937e7b78c2d89db3809274130df4eLajos Molnar                            mCodec->mBuffers[kPortIndexOutput].size());
60790806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    err = FAILED_TRANSACTION;
60800806340688c937e7b78c2d89db3809274130df4eLajos Molnar                } else {
60810806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->mDealer[kPortIndexOutput].clear();
60820806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
6083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
60840806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err == OK) {
60850806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    err = mCodec->mOMX->sendCommand(
60860806340688c937e7b78c2d89db3809274130df4eLajos Molnar                            mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput);
60870806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
6088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
60890806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err == OK) {
60900806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    err = mCodec->allocateBuffersOnPort(kPortIndexOutput);
60910806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGE_IF(err != OK, "Failed to allocate output port buffers after port "
60920806340688c937e7b78c2d89db3809274130df4eLajos Molnar                            "reconfiguration: (%d)", err);
60930806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
6094cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
60950806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err != OK) {
6096251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
6097d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
6098755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // This is technically not correct, but appears to be
6099755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the only way to free the component instance.
6100755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // Controlled transitioning from excecuting->idle
6101755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // and idle->loaded seem impossible probably because
6102755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the output port never finishes re-enabling.
6103755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mShutdownInProgress = true;
6104755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mKeepComponentAllocated = false;
6105755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->changeState(mCodec->mLoadedState);
6106cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                }
6107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
6109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
6110777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (data2 != (OMX_U32)kPortIndexOutput) {
6111777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGW("ignoring EventCmdComplete OMX_CommandPortEnable for port %u", data2);
6112777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return false;
6113777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
6114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
611531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
611631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
61170806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGV("[%s] Output port now reenabled.", mCodec->mComponentName.c_str());
6118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6119349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                if (mCodec->mExecutingState->active()) {
6120349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    mCodec->mExecutingState->submitOutputBuffers();
6121349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                }
6122349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mExecutingState);
6124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
6126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
6127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
6129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
6133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
6137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6138f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
61395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : BaseState(codec),
61405778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mComponentNowIdle(false) {
6141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6143f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
6144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
6145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
6147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
6148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
6150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
61510806340688c937e7b78c2d89db3809274130df4eLajos Molnar            ALOGW("Ignoring flush request in ExecutingToIdleState");
6152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
6156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
6158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
6165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
6169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6171f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::stateEntered() {
61723856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
617331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
61745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mComponentNowIdle = false;
617531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mCodec->mSentFormat = false;
6176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6178f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onOMXEvent(
6179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
6181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
6182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
61830806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandStateSet
61840806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    || data2 != (OMX_U32)OMX_StateIdle) {
61850806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("Unexpected command completion in ExecutingToIdleState: %s(%u) %s(%u)",
61860806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1,
61870806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_STATETYPE)data2), data2);
61880806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
61890806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
61900806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
61925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mComponentNowIdle = true;
61935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            changeStateIfWeOwnAllBuffers();
6195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6199349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
6200349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventBufferFlag:
6201349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
6202349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We're shutting down and don't care about this anymore.
6203349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
6204349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
6205349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
6208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
62100af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
6211f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
62125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
62130806340688c937e7b78c2d89db3809274130df4eLajos Molnar        status_t err = mCodec->mOMX->sendCommand(
62140806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded);
62150806340688c937e7b78c2d89db3809274130df4eLajos Molnar        if (err == OK) {
62160806340688c937e7b78c2d89db3809274130df4eLajos Molnar            err = mCodec->freeBuffersOnPort(kPortIndexInput);
62170806340688c937e7b78c2d89db3809274130df4eLajos Molnar            status_t err2 = mCodec->freeBuffersOnPort(kPortIndexOutput);
62180806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err == OK) {
62190806340688c937e7b78c2d89db3809274130df4eLajos Molnar                err = err2;
62200806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
62210806340688c937e7b78c2d89db3809274130df4eLajos Molnar        }
6222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
62230167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown)
62240167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && mCodec->mNativeWindow != NULL) {
6225bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // We push enough 1x1 blank buffers to ensure that one of
6226bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // them has made it to the display.  This allows the OMX
6227bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // component teardown to zero out any protected buffers
6228bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // without the risk of scanning out one of those buffers.
6229b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar            pushBlankBuffersToNativeWindow(mCodec->mNativeWindow.get());
6230bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
6231bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
62320806340688c937e7b78c2d89db3809274130df4eLajos Molnar        if (err != OK) {
62330806340688c937e7b78c2d89db3809274130df4eLajos Molnar            mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
62340806340688c937e7b78c2d89db3809274130df4eLajos Molnar            return;
62350806340688c937e7b78c2d89db3809274130df4eLajos Molnar        }
62360806340688c937e7b78c2d89db3809274130df4eLajos Molnar
6237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mIdleToLoadedState);
6238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6241f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onInputBufferFilled(
6242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
6243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
6244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
6246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6248f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onOutputBufferDrained(
6249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
6250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
6251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
6253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
6256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6257f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
6258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
6259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6261f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
6262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
6263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
6265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
6266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
6268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
6274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
6276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
62770806340688c937e7b78c2d89db3809274130df4eLajos Molnar            ALOGE("Got flush request in IdleToLoadedState");
6278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
6283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
6287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6289f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToLoadedState::stateEntered() {
62903856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
6291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6293f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onOMXEvent(
6294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
6296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
6297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
62980806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandStateSet
62990806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    || data2 != (OMX_U32)OMX_StateLoaded) {
63000806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("Unexpected command completion in IdleToLoadedState: %s(%u) %s(%u)",
63010806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1,
63020806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_STATETYPE)data2), data2);
63030806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
63040806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
63050806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6307c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->changeState(mCodec->mLoadedState);
6308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
6314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
6318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6319f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::FlushingState::FlushingState(ACodec *codec)
6320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
6321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6323f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::stateEntered() {
63243856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
6325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
6327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6329f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
6330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
6331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
6333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
6334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
6336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
6340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing this right now.
6342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
6348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
6352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6354f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onOMXEvent(
6355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6356ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGV("[%s] FlushingState onOMXEvent(%u,%d)",
6357ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar            mCodec->mComponentName.c_str(), event, (OMX_S32)data1);
6358d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
6359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
6360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
6361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
63620806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandFlush) {
63630806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("unexpected EventCmdComplete %s(%d) data2:%d in FlushingState",
63640806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1, data2);
63650806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
63660806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
63670806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
6370777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (mFlushComplete[data2]) {
6371777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGW("Flush already completed for %s port",
6372777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            data2 == kPortIndexInput ? "input" : "output");
6373777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return true;
6374777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
6375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mFlushComplete[data2] = true;
6376e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber
63770806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (mFlushComplete[kPortIndexInput] && mFlushComplete[kPortIndexOutput]) {
6378e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                    changeStateIfWeOwnAllBuffers();
6379e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                }
6380777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            } else if (data2 == OMX_ALL) {
6381777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (!mFlushComplete[kPortIndexInput] || !mFlushComplete[kPortIndexOutput]) {
6382777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGW("received flush complete event for OMX_ALL before ports have been"
6383777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            "flushed (%d/%d)",
6384777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mFlushComplete[kPortIndexInput], mFlushComplete[kPortIndexOutput]);
6385777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return false;
6386777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
6387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                changeStateIfWeOwnAllBuffers();
6389777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            } else {
6390777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                ALOGW("data2 not OMX_ALL but %u in EventCmdComplete CommandFlush", data2);
6391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
6392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6396349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
6397349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
63981d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec);
6399349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("type", omx_message::EVENT);
6400609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            msg->setInt32("node", mCodec->mNode);
6401349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("event", event);
6402349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data1", data1);
6403349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data2", data2);
6404349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
64053856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
6406349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                 mCodec->mComponentName.c_str());
6407349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6408349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mCodec->deferMessage(msg);
6409349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6410349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
6411349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
6412349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
6415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
6418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6420f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
6421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
6422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
6424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6426f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
6427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
6428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
6430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6432f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
6433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mFlushComplete[kPortIndexInput]
6434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mFlushComplete[kPortIndexOutput]
6435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mCodec->allYourBuffersAreBelongToUs()) {
64367e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // We now own all buffers except possibly those still queued with
64377e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // the native window for rendering. Let's get those back as well.
64387e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
64397e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
6440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
6441d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatFlushCompleted);
6442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->post();
6443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->mPortEOS[kPortIndexInput] =
6445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mPortEOS[kPortIndexOutput] = false;
6446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6447dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber        mCodec->mInputEOSResult = OK;
6448dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
6449f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        if (mCodec->mSkipCutBuffer != NULL) {
6450f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen            mCodec->mSkipCutBuffer->clear();
6451f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        }
6452f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen
6453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mExecutingState);
6454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
6458