ACodec.cpp revision 9847fcefb183e1cb09eb48e17a09577392b0e8f4
196ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk/*
296ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk * Copyright (C) 2010 The Android Open Source Project
396ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk *
496ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk * Licensed under the Apache License, Version 2.0 (the "License");
596ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk * you may not use this file except in compliance with the License.
696ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk * You may obtain a copy of the License at
796ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk *
896ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk *      http://www.apache.org/licenses/LICENSE-2.0
996ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk *
1096ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk * Unless required by applicable law or agreed to in writing, software
1196ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk * distributed under the License is distributed on an "AS IS" BASIS,
1296ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1396ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk * See the License for the specific language governing permissions and
1496ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk * limitations under the License.
1596ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk */
1696ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk
1796ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk//#define LOG_NDEBUG 0
1896ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk#define LOG_TAG "ACodec"
1996ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk
2096ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk#ifdef __LP64__
21a5d7dd9cd5401d430d7bdb942ed98eb1eb939d26Jason Monk#define OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
2296ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk#endif
230193a87196f5c027b82285e711d8a13e41e4c7d8Jason Monk
2496ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk#include <inttypes.h>
25a5d7dd9cd5401d430d7bdb942ed98eb1eb939d26Jason Monk#include <utils/Trace.h>
2696ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk
2796ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk#include <gui/Surface.h>
2896ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk
2996ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk#include <media/stagefright/ACodec.h>
3096ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk
3196ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk#include <binder/MemoryDealer.h>
3296ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk
3396ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk#include <media/stagefright/foundation/hexdump.h>
3496ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk#include <media/stagefright/foundation/ABuffer.h>
3596ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk#include <media/stagefright/foundation/ADebug.h>
3696ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk#include <media/stagefright/foundation/AMessage.h>
3796ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk#include <media/stagefright/foundation/AUtils.h>
3896ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk
3996ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk#include <media/stagefright/BufferProducerWrapper.h>
4096ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk#include <media/stagefright/MediaCodecList.h>
4196ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk#include <media/stagefright/MediaDefs.h>
4296ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk#include <media/stagefright/OMXClient.h>
4396ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk#include <media/stagefright/OMXCodec.h>
4496ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk#include <media/stagefright/PersistentSurface.h>
4596ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk#include <media/stagefright/SurfaceUtils.h>
4696ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk#include <media/hardware/HardwareAPI.h>
4796ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk
4896ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk#include <OMX_AudioExt.h>
4996ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk#include <OMX_VideoExt.h>
5096ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk#include <OMX_Component.h>
5196ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk#include <OMX_IndexExt.h>
5296ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk#include <OMX_AsString.h>
5396ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk
5496ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk#include "include/avc_utils.h"
5596ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk
5696ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monknamespace android {
5796ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk
5896ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk// OMX errors are directly mapped into status_t range if
5996ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk// there is no corresponding MediaError status code.
6096ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk// Use the statusFromOMXError(int32_t omxError) function.
6196ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk//
6296ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk// Currently this is a direct map.
6396ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk// See frameworks/native/include/media/openmax/OMX_Core.h
64a5d7dd9cd5401d430d7bdb942ed98eb1eb939d26Jason Monk//
65a5d7dd9cd5401d430d7bdb942ed98eb1eb939d26Jason Monk// Vendor OMX errors     from 0x90000000 - 0x9000FFFF
66a5d7dd9cd5401d430d7bdb942ed98eb1eb939d26Jason Monk// Extension OMX errors  from 0x8F000000 - 0x90000000
67a5d7dd9cd5401d430d7bdb942ed98eb1eb939d26Jason Monk// Standard OMX errors   from 0x80001000 - 0x80001024 (0x80001024 current)
68a5d7dd9cd5401d430d7bdb942ed98eb1eb939d26Jason Monk//
69a5d7dd9cd5401d430d7bdb942ed98eb1eb939d26Jason Monk
70a5d7dd9cd5401d430d7bdb942ed98eb1eb939d26Jason Monk// returns true if err is a recognized OMX error code.
71a5d7dd9cd5401d430d7bdb942ed98eb1eb939d26Jason Monk// as OMX error is OMX_S32, this is an int32_t type
72a5d7dd9cd5401d430d7bdb942ed98eb1eb939d26Jason Monkstatic inline bool isOMXError(int32_t err) {
73a5d7dd9cd5401d430d7bdb942ed98eb1eb939d26Jason Monk    return (ERROR_CODEC_MIN <= err && err <= ERROR_CODEC_MAX);
74a5d7dd9cd5401d430d7bdb942ed98eb1eb939d26Jason Monk}
75a5d7dd9cd5401d430d7bdb942ed98eb1eb939d26Jason Monk
76a5d7dd9cd5401d430d7bdb942ed98eb1eb939d26Jason Monk// converts an OMX error to a status_t
77a5d7dd9cd5401d430d7bdb942ed98eb1eb939d26Jason Monkstatic inline status_t statusFromOMXError(int32_t omxError) {
78a5d7dd9cd5401d430d7bdb942ed98eb1eb939d26Jason Monk    switch (omxError) {
79a5d7dd9cd5401d430d7bdb942ed98eb1eb939d26Jason Monk    case OMX_ErrorInvalidComponentName:
80a5d7dd9cd5401d430d7bdb942ed98eb1eb939d26Jason Monk    case OMX_ErrorComponentNotFound:
81a5d7dd9cd5401d430d7bdb942ed98eb1eb939d26Jason Monk        return NAME_NOT_FOUND; // can trigger illegal argument error for provided names.
8296ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk    default:
8396ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk        return isOMXError(omxError) ? omxError : 0; // no translation required
8496ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk    }
8596ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk}
8696ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk
8796ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk// checks and converts status_t to a non-side-effect status_t
8896ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monkstatic inline status_t makeNoSideEffectStatus(status_t err) {
8996ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk    switch (err) {
9096ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk    // the following errors have side effects and may come
9196ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk    // from other code modules. Remap for safety reasons.
9296ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk    case INVALID_OPERATION:
9396ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk    case DEAD_OBJECT:
9496ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk        return UNKNOWN_ERROR;
9596ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk    default:
9696ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk        return err;
9796ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk    }
9896ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk}
9996ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk
10096ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monktemplate<class T>
10196ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monkstatic void InitOMXParams(T *params) {
1020193a87196f5c027b82285e711d8a13e41e4c7d8Jason Monk    params->nSize = sizeof(T);
1030193a87196f5c027b82285e711d8a13e41e4c7d8Jason Monk    params->nVersion.s.nVersionMajor = 1;
1040193a87196f5c027b82285e711d8a13e41e4c7d8Jason Monk    params->nVersion.s.nVersionMinor = 0;
1050193a87196f5c027b82285e711d8a13e41e4c7d8Jason Monk    params->nVersion.s.nRevision = 0;
1060193a87196f5c027b82285e711d8a13e41e4c7d8Jason Monk    params->nVersion.s.nStep = 0;
1070193a87196f5c027b82285e711d8a13e41e4c7d8Jason Monk}
1080193a87196f5c027b82285e711d8a13e41e4c7d8Jason Monk
1090193a87196f5c027b82285e711d8a13e41e4c7d8Jason Monkstruct CodecObserver : public BnOMXObserver {
1100193a87196f5c027b82285e711d8a13e41e4c7d8Jason Monk    CodecObserver() {}
1110193a87196f5c027b82285e711d8a13e41e4c7d8Jason Monk
1120193a87196f5c027b82285e711d8a13e41e4c7d8Jason Monk    void setNotificationMessage(const sp<AMessage> &msg) {
1130193a87196f5c027b82285e711d8a13e41e4c7d8Jason Monk        mNotify = msg;
1140193a87196f5c027b82285e711d8a13e41e4c7d8Jason Monk    }
1150193a87196f5c027b82285e711d8a13e41e4c7d8Jason Monk
1160193a87196f5c027b82285e711d8a13e41e4c7d8Jason Monk    // from IOMXObserver
1170193a87196f5c027b82285e711d8a13e41e4c7d8Jason Monk    virtual void onMessage(const omx_message &omx_msg) {
1180193a87196f5c027b82285e711d8a13e41e4c7d8Jason Monk        sp<AMessage> msg = mNotify->dup();
1190193a87196f5c027b82285e711d8a13e41e4c7d8Jason Monk
1200193a87196f5c027b82285e711d8a13e41e4c7d8Jason Monk        msg->setInt32("type", omx_msg.type);
1210193a87196f5c027b82285e711d8a13e41e4c7d8Jason Monk        msg->setInt32("node", omx_msg.node);
12296ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk
12396ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk        switch (omx_msg.type) {
12496ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk            case omx_message::EVENT:
12596ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk            {
12696ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk                msg->setInt32("event", omx_msg.u.event_data.event);
12796ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk                msg->setInt32("data1", omx_msg.u.event_data.data1);
12896ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk                msg->setInt32("data2", omx_msg.u.event_data.data2);
12996ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk                break;
13096ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk            }
13196ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk
13296ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk            case omx_message::EMPTY_BUFFER_DONE:
13396ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk            {
13496ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk                msg->setInt32("buffer", omx_msg.u.buffer_data.buffer);
13596ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk                msg->setInt32("fence_fd", omx_msg.fenceFd);
13696ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk                break;
13796ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk            }
13896ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk
13996ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk            case omx_message::FILL_BUFFER_DONE:
14096ab63640f186dd7f983b35f2c4e1a95436e5052Jason Monk            {
141                msg->setInt32(
142                        "buffer", omx_msg.u.extended_buffer_data.buffer);
143                msg->setInt32(
144                        "range_offset",
145                        omx_msg.u.extended_buffer_data.range_offset);
146                msg->setInt32(
147                        "range_length",
148                        omx_msg.u.extended_buffer_data.range_length);
149                msg->setInt32(
150                        "flags",
151                        omx_msg.u.extended_buffer_data.flags);
152                msg->setInt64(
153                        "timestamp",
154                        omx_msg.u.extended_buffer_data.timestamp);
155                msg->setInt32(
156                        "fence_fd", omx_msg.fenceFd);
157                break;
158            }
159
160            default:
161                ALOGE("Unrecognized message type: %d", omx_msg.type);
162                break;
163        }
164
165        msg->post();
166    }
167
168protected:
169    virtual ~CodecObserver() {}
170
171private:
172    sp<AMessage> mNotify;
173
174    DISALLOW_EVIL_CONSTRUCTORS(CodecObserver);
175};
176
177////////////////////////////////////////////////////////////////////////////////
178
179struct ACodec::BaseState : public AState {
180    BaseState(ACodec *codec, const sp<AState> &parentState = NULL);
181
182protected:
183    enum PortMode {
184        KEEP_BUFFERS,
185        RESUBMIT_BUFFERS,
186        FREE_BUFFERS,
187    };
188
189    ACodec *mCodec;
190
191    virtual PortMode getPortMode(OMX_U32 portIndex);
192
193    virtual bool onMessageReceived(const sp<AMessage> &msg);
194
195    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
196
197    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
198    virtual void onInputBufferFilled(const sp<AMessage> &msg);
199
200    void postFillThisBuffer(BufferInfo *info);
201
202private:
203    bool onOMXMessage(const sp<AMessage> &msg);
204
205    bool onOMXEmptyBufferDone(IOMX::buffer_id bufferID, int fenceFd);
206
207    bool onOMXFillBufferDone(
208            IOMX::buffer_id bufferID,
209            size_t rangeOffset, size_t rangeLength,
210            OMX_U32 flags,
211            int64_t timeUs,
212            int fenceFd);
213
214    void getMoreInputDataIfPossible();
215
216    DISALLOW_EVIL_CONSTRUCTORS(BaseState);
217};
218
219////////////////////////////////////////////////////////////////////////////////
220
221struct ACodec::DeathNotifier : public IBinder::DeathRecipient {
222    DeathNotifier(const sp<AMessage> &notify)
223        : mNotify(notify) {
224    }
225
226    virtual void binderDied(const wp<IBinder> &) {
227        mNotify->post();
228    }
229
230protected:
231    virtual ~DeathNotifier() {}
232
233private:
234    sp<AMessage> mNotify;
235
236    DISALLOW_EVIL_CONSTRUCTORS(DeathNotifier);
237};
238
239struct ACodec::UninitializedState : public ACodec::BaseState {
240    UninitializedState(ACodec *codec);
241
242protected:
243    virtual bool onMessageReceived(const sp<AMessage> &msg);
244    virtual void stateEntered();
245
246private:
247    void onSetup(const sp<AMessage> &msg);
248    bool onAllocateComponent(const sp<AMessage> &msg);
249
250    sp<DeathNotifier> mDeathNotifier;
251
252    DISALLOW_EVIL_CONSTRUCTORS(UninitializedState);
253};
254
255////////////////////////////////////////////////////////////////////////////////
256
257struct ACodec::LoadedState : public ACodec::BaseState {
258    LoadedState(ACodec *codec);
259
260protected:
261    virtual bool onMessageReceived(const sp<AMessage> &msg);
262    virtual void stateEntered();
263
264private:
265    friend struct ACodec::UninitializedState;
266
267    bool onConfigureComponent(const sp<AMessage> &msg);
268    void onCreateInputSurface(const sp<AMessage> &msg);
269    void onSetInputSurface(const sp<AMessage> &msg);
270    void onStart();
271    void onShutdown(bool keepComponentAllocated);
272
273    status_t setupInputSurface();
274
275    DISALLOW_EVIL_CONSTRUCTORS(LoadedState);
276};
277
278////////////////////////////////////////////////////////////////////////////////
279
280struct ACodec::LoadedToIdleState : public ACodec::BaseState {
281    LoadedToIdleState(ACodec *codec);
282
283protected:
284    virtual bool onMessageReceived(const sp<AMessage> &msg);
285    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
286    virtual void stateEntered();
287
288private:
289    status_t allocateBuffers();
290
291    DISALLOW_EVIL_CONSTRUCTORS(LoadedToIdleState);
292};
293
294////////////////////////////////////////////////////////////////////////////////
295
296struct ACodec::IdleToExecutingState : public ACodec::BaseState {
297    IdleToExecutingState(ACodec *codec);
298
299protected:
300    virtual bool onMessageReceived(const sp<AMessage> &msg);
301    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
302    virtual void stateEntered();
303
304private:
305    DISALLOW_EVIL_CONSTRUCTORS(IdleToExecutingState);
306};
307
308////////////////////////////////////////////////////////////////////////////////
309
310struct ACodec::ExecutingState : public ACodec::BaseState {
311    ExecutingState(ACodec *codec);
312
313    void submitRegularOutputBuffers();
314    void submitOutputMetaBuffers();
315    void submitOutputBuffers();
316
317    // Submit output buffers to the decoder, submit input buffers to client
318    // to fill with data.
319    void resume();
320
321    // Returns true iff input and output buffers are in play.
322    bool active() const { return mActive; }
323
324protected:
325    virtual PortMode getPortMode(OMX_U32 portIndex);
326    virtual bool onMessageReceived(const sp<AMessage> &msg);
327    virtual void stateEntered();
328
329    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
330
331private:
332    bool mActive;
333
334    DISALLOW_EVIL_CONSTRUCTORS(ExecutingState);
335};
336
337////////////////////////////////////////////////////////////////////////////////
338
339struct ACodec::OutputPortSettingsChangedState : public ACodec::BaseState {
340    OutputPortSettingsChangedState(ACodec *codec);
341
342protected:
343    virtual PortMode getPortMode(OMX_U32 portIndex);
344    virtual bool onMessageReceived(const sp<AMessage> &msg);
345    virtual void stateEntered();
346
347    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
348
349private:
350    DISALLOW_EVIL_CONSTRUCTORS(OutputPortSettingsChangedState);
351};
352
353////////////////////////////////////////////////////////////////////////////////
354
355struct ACodec::ExecutingToIdleState : public ACodec::BaseState {
356    ExecutingToIdleState(ACodec *codec);
357
358protected:
359    virtual bool onMessageReceived(const sp<AMessage> &msg);
360    virtual void stateEntered();
361
362    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
363
364    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
365    virtual void onInputBufferFilled(const sp<AMessage> &msg);
366
367private:
368    void changeStateIfWeOwnAllBuffers();
369
370    bool mComponentNowIdle;
371
372    DISALLOW_EVIL_CONSTRUCTORS(ExecutingToIdleState);
373};
374
375////////////////////////////////////////////////////////////////////////////////
376
377struct ACodec::IdleToLoadedState : public ACodec::BaseState {
378    IdleToLoadedState(ACodec *codec);
379
380protected:
381    virtual bool onMessageReceived(const sp<AMessage> &msg);
382    virtual void stateEntered();
383
384    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
385
386private:
387    DISALLOW_EVIL_CONSTRUCTORS(IdleToLoadedState);
388};
389
390////////////////////////////////////////////////////////////////////////////////
391
392struct ACodec::FlushingState : public ACodec::BaseState {
393    FlushingState(ACodec *codec);
394
395protected:
396    virtual bool onMessageReceived(const sp<AMessage> &msg);
397    virtual void stateEntered();
398
399    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
400
401    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
402    virtual void onInputBufferFilled(const sp<AMessage> &msg);
403
404private:
405    bool mFlushComplete[2];
406
407    void changeStateIfWeOwnAllBuffers();
408
409    DISALLOW_EVIL_CONSTRUCTORS(FlushingState);
410};
411
412////////////////////////////////////////////////////////////////////////////////
413
414void ACodec::BufferInfo::setWriteFence(int fenceFd, const char *dbg) {
415    if (mFenceFd >= 0) {
416        ALOGW("OVERWRITE OF %s fence %d by write fence %d in %s",
417                mIsReadFence ? "read" : "write", mFenceFd, fenceFd, dbg);
418    }
419    mFenceFd = fenceFd;
420    mIsReadFence = false;
421}
422
423void ACodec::BufferInfo::setReadFence(int fenceFd, const char *dbg) {
424    if (mFenceFd >= 0) {
425        ALOGW("OVERWRITE OF %s fence %d by read fence %d in %s",
426                mIsReadFence ? "read" : "write", mFenceFd, fenceFd, dbg);
427    }
428    mFenceFd = fenceFd;
429    mIsReadFence = true;
430}
431
432void ACodec::BufferInfo::checkWriteFence(const char *dbg) {
433    if (mFenceFd >= 0 && mIsReadFence) {
434        ALOGD("REUSING read fence %d as write fence in %s", mFenceFd, dbg);
435    }
436}
437
438void ACodec::BufferInfo::checkReadFence(const char *dbg) {
439    if (mFenceFd >= 0 && !mIsReadFence) {
440        ALOGD("REUSING write fence %d as read fence in %s", mFenceFd, dbg);
441    }
442}
443
444////////////////////////////////////////////////////////////////////////////////
445
446ACodec::ACodec()
447    : mQuirks(0),
448      mNode(0),
449      mSentFormat(false),
450      mIsVideo(false),
451      mIsEncoder(false),
452      mShutdownInProgress(false),
453      mExplicitShutdown(false),
454      mEncoderDelay(0),
455      mEncoderPadding(0),
456      mRotationDegrees(0),
457      mChannelMaskPresent(false),
458      mChannelMask(0),
459      mDequeueCounter(0),
460      mInputMetadataType(kMetadataBufferTypeInvalid),
461      mOutputMetadataType(kMetadataBufferTypeInvalid),
462      mLegacyAdaptiveExperiment(false),
463      mMetadataBuffersToSubmit(0),
464      mRepeatFrameDelayUs(-1ll),
465      mMaxPtsGapUs(-1ll),
466      mMaxFps(-1),
467      mTimePerFrameUs(-1ll),
468      mTimePerCaptureUs(-1ll),
469      mCreateInputBuffersSuspended(false),
470      mTunneled(false) {
471    mUninitializedState = new UninitializedState(this);
472    mLoadedState = new LoadedState(this);
473    mLoadedToIdleState = new LoadedToIdleState(this);
474    mIdleToExecutingState = new IdleToExecutingState(this);
475    mExecutingState = new ExecutingState(this);
476
477    mOutputPortSettingsChangedState =
478        new OutputPortSettingsChangedState(this);
479
480    mExecutingToIdleState = new ExecutingToIdleState(this);
481    mIdleToLoadedState = new IdleToLoadedState(this);
482    mFlushingState = new FlushingState(this);
483
484    mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
485    mInputEOSResult = OK;
486
487    changeState(mUninitializedState);
488}
489
490ACodec::~ACodec() {
491}
492
493void ACodec::setNotificationMessage(const sp<AMessage> &msg) {
494    mNotify = msg;
495}
496
497void ACodec::initiateSetup(const sp<AMessage> &msg) {
498    msg->setWhat(kWhatSetup);
499    msg->setTarget(this);
500    msg->post();
501}
502
503void ACodec::signalSetParameters(const sp<AMessage> &params) {
504    sp<AMessage> msg = new AMessage(kWhatSetParameters, this);
505    msg->setMessage("params", params);
506    msg->post();
507}
508
509void ACodec::initiateAllocateComponent(const sp<AMessage> &msg) {
510    msg->setWhat(kWhatAllocateComponent);
511    msg->setTarget(this);
512    msg->post();
513}
514
515void ACodec::initiateConfigureComponent(const sp<AMessage> &msg) {
516    msg->setWhat(kWhatConfigureComponent);
517    msg->setTarget(this);
518    msg->post();
519}
520
521status_t ACodec::setSurface(const sp<Surface> &surface) {
522    sp<AMessage> msg = new AMessage(kWhatSetSurface, this);
523    msg->setObject("surface", surface);
524
525    sp<AMessage> response;
526    status_t err = msg->postAndAwaitResponse(&response);
527
528    if (err == OK) {
529        (void)response->findInt32("err", &err);
530    }
531    return err;
532}
533
534void ACodec::initiateCreateInputSurface() {
535    (new AMessage(kWhatCreateInputSurface, this))->post();
536}
537
538void ACodec::initiateSetInputSurface(
539        const sp<PersistentSurface> &surface) {
540    sp<AMessage> msg = new AMessage(kWhatSetInputSurface, this);
541    msg->setObject("input-surface", surface);
542    msg->post();
543}
544
545void ACodec::signalEndOfInputStream() {
546    (new AMessage(kWhatSignalEndOfInputStream, this))->post();
547}
548
549void ACodec::initiateStart() {
550    (new AMessage(kWhatStart, this))->post();
551}
552
553void ACodec::signalFlush() {
554    ALOGV("[%s] signalFlush", mComponentName.c_str());
555    (new AMessage(kWhatFlush, this))->post();
556}
557
558void ACodec::signalResume() {
559    (new AMessage(kWhatResume, this))->post();
560}
561
562void ACodec::initiateShutdown(bool keepComponentAllocated) {
563    sp<AMessage> msg = new AMessage(kWhatShutdown, this);
564    msg->setInt32("keepComponentAllocated", keepComponentAllocated);
565    msg->post();
566    if (!keepComponentAllocated) {
567        // ensure shutdown completes in 3 seconds
568        (new AMessage(kWhatReleaseCodecInstance, this))->post(3000000);
569    }
570}
571
572void ACodec::signalRequestIDRFrame() {
573    (new AMessage(kWhatRequestIDRFrame, this))->post();
574}
575
576// *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
577// Some codecs may return input buffers before having them processed.
578// This causes a halt if we already signaled an EOS on the input
579// port.  For now keep submitting an output buffer if there was an
580// EOS on the input port, but not yet on the output port.
581void ACodec::signalSubmitOutputMetadataBufferIfEOS_workaround() {
582    if (mPortEOS[kPortIndexInput] && !mPortEOS[kPortIndexOutput] &&
583            mMetadataBuffersToSubmit > 0) {
584        (new AMessage(kWhatSubmitOutputMetadataBufferIfEOS, this))->post();
585    }
586}
587
588status_t ACodec::handleSetSurface(const sp<Surface> &surface) {
589    // allow keeping unset surface
590    if (surface == NULL) {
591        if (mNativeWindow != NULL) {
592            ALOGW("cannot unset a surface");
593            return INVALID_OPERATION;
594        }
595        return OK;
596    }
597
598    // allow keeping unset surface
599    if (mNativeWindow == NULL) {
600        ALOGW("component was not configured with a surface");
601        return INVALID_OPERATION;
602    }
603
604    ANativeWindow *nativeWindow = surface.get();
605    // if we have not yet started the codec, we can simply set the native window
606    if (mBuffers[kPortIndexInput].size() == 0) {
607        mNativeWindow = surface;
608        return OK;
609    }
610
611    // we do not support changing a tunneled surface after start
612    if (mTunneled) {
613        ALOGW("cannot change tunneled surface");
614        return INVALID_OPERATION;
615    }
616
617    status_t err = setupNativeWindowSizeFormatAndUsage(nativeWindow);
618    if (err != OK) {
619        return err;
620    }
621
622    // get min undequeued count. We cannot switch to a surface that has a higher
623    // undequeued count than we allocated.
624    int minUndequeuedBuffers = 0;
625    err = nativeWindow->query(
626            nativeWindow, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
627            &minUndequeuedBuffers);
628    if (err != 0) {
629        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
630                strerror(-err), -err);
631        return err;
632    }
633    if (minUndequeuedBuffers > (int)mNumUndequeuedBuffers) {
634        ALOGE("new surface holds onto more buffers (%d) than planned for (%zu)",
635                minUndequeuedBuffers, mNumUndequeuedBuffers);
636        return BAD_VALUE;
637    }
638
639    // we cannot change the number of output buffers while OMX is running
640    // set up surface to the same count
641    Vector<BufferInfo> &buffers = mBuffers[kPortIndexOutput];
642    ALOGV("setting up surface for %zu buffers", buffers.size());
643
644    err = native_window_set_buffer_count(nativeWindow, buffers.size());
645    if (err != 0) {
646        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
647                -err);
648        return err;
649    }
650
651    // need to enable allocation when attaching
652    surface->getIGraphicBufferProducer()->allowAllocation(true);
653
654    // for meta data mode, we move dequeud buffers to the new surface.
655    // for non-meta mode, we must move all registered buffers
656    for (size_t i = 0; i < buffers.size(); ++i) {
657        const BufferInfo &info = buffers[i];
658        // skip undequeued buffers for meta data mode
659        if (storingMetadataInDecodedBuffers()
660                && !mLegacyAdaptiveExperiment
661                && info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
662            ALOGV("skipping buffer %p", info.mGraphicBuffer->getNativeBuffer());
663            continue;
664        }
665        ALOGV("attaching buffer %p", info.mGraphicBuffer->getNativeBuffer());
666
667        err = surface->attachBuffer(info.mGraphicBuffer->getNativeBuffer());
668        if (err != OK) {
669            ALOGE("failed to attach buffer %p to the new surface: %s (%d)",
670                    info.mGraphicBuffer->getNativeBuffer(),
671                    strerror(-err), -err);
672            return err;
673        }
674    }
675
676    // cancel undequeued buffers to new surface
677    if (!storingMetadataInDecodedBuffers() || mLegacyAdaptiveExperiment) {
678        for (size_t i = 0; i < buffers.size(); ++i) {
679            BufferInfo &info = buffers.editItemAt(i);
680            if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
681                ALOGV("canceling buffer %p", info.mGraphicBuffer->getNativeBuffer());
682                err = nativeWindow->cancelBuffer(
683                        nativeWindow, info.mGraphicBuffer->getNativeBuffer(), info.mFenceFd);
684                info.mFenceFd = -1;
685                if (err != OK) {
686                    ALOGE("failed to cancel buffer %p to the new surface: %s (%d)",
687                            info.mGraphicBuffer->getNativeBuffer(),
688                            strerror(-err), -err);
689                    return err;
690                }
691            }
692        }
693        // disallow further allocation
694        (void)surface->getIGraphicBufferProducer()->allowAllocation(false);
695    }
696
697    // push blank buffers to previous window if requested
698    if (mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown) {
699        pushBlankBuffersToNativeWindow(mNativeWindow.get());
700    }
701
702    mNativeWindow = nativeWindow;
703    return OK;
704}
705
706status_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
707    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
708
709    CHECK(mDealer[portIndex] == NULL);
710    CHECK(mBuffers[portIndex].isEmpty());
711
712    status_t err;
713    if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
714        if (storingMetadataInDecodedBuffers()) {
715            err = allocateOutputMetadataBuffers();
716        } else {
717            err = allocateOutputBuffersFromNativeWindow();
718        }
719    } else {
720        OMX_PARAM_PORTDEFINITIONTYPE def;
721        InitOMXParams(&def);
722        def.nPortIndex = portIndex;
723
724        err = mOMX->getParameter(
725                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
726
727        if (err == OK) {
728            MetadataBufferType type =
729                portIndex == kPortIndexOutput ? mOutputMetadataType : mInputMetadataType;
730            int32_t bufSize = def.nBufferSize;
731            if (type == kMetadataBufferTypeGrallocSource) {
732                bufSize = sizeof(VideoGrallocMetadata);
733            } else if (type == kMetadataBufferTypeANWBuffer) {
734                bufSize = sizeof(VideoNativeMetadata);
735            }
736
737            // If using gralloc or native source input metadata buffers, allocate largest
738            // metadata size as we prefer to generate native source metadata, but component
739            // may require gralloc source.
740            int32_t allottedSize = bufSize;
741            if (portIndex == kPortIndexInput && type > 0) {
742                bufSize = max(sizeof(VideoGrallocMetadata), sizeof(VideoNativeMetadata));
743            }
744
745            ALOGV("[%s] Allocating %u buffers of size %d/%d (from %u using %s) on %s port",
746                    mComponentName.c_str(),
747                    def.nBufferCountActual, bufSize, allottedSize, def.nBufferSize, asString(type),
748                    portIndex == kPortIndexInput ? "input" : "output");
749
750            size_t totalSize = def.nBufferCountActual * bufSize;
751            mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
752
753            for (OMX_U32 i = 0; i < def.nBufferCountActual && err == OK; ++i) {
754                sp<IMemory> mem = mDealer[portIndex]->allocate(bufSize);
755                if (mem == NULL || mem->pointer() == NULL) {
756                    return NO_MEMORY;
757                }
758
759                BufferInfo info;
760                info.mStatus = BufferInfo::OWNED_BY_US;
761                info.mFenceFd = -1;
762
763                uint32_t requiresAllocateBufferBit =
764                    (portIndex == kPortIndexInput)
765                        ? OMXCodec::kRequiresAllocateBufferOnInputPorts
766                        : OMXCodec::kRequiresAllocateBufferOnOutputPorts;
767
768                if ((portIndex == kPortIndexInput && (mFlags & kFlagIsSecure))
769                        || (portIndex == kPortIndexOutput && usingMetadataOnEncoderOutput())) {
770                    mem.clear();
771
772                    void *ptr;
773                    err = mOMX->allocateBuffer(
774                            mNode, portIndex, bufSize, &info.mBufferID,
775                            &ptr);
776
777                    info.mData = new ABuffer(ptr, bufSize);
778                } else if (mQuirks & requiresAllocateBufferBit) {
779                    err = mOMX->allocateBufferWithBackup(
780                            mNode, portIndex, mem, &info.mBufferID, allottedSize);
781                } else {
782                    err = mOMX->useBuffer(mNode, portIndex, mem, &info.mBufferID, allottedSize);
783                }
784
785                if (mem != NULL) {
786                    info.mData = new ABuffer(mem->pointer(), bufSize);
787                    if (type == kMetadataBufferTypeANWBuffer) {
788                        ((VideoNativeMetadata *)mem->pointer())->nFenceFd = -1;
789                    }
790                }
791
792                mBuffers[portIndex].push(info);
793            }
794        }
795    }
796
797    if (err != OK) {
798        return err;
799    }
800
801    sp<AMessage> notify = mNotify->dup();
802    notify->setInt32("what", CodecBase::kWhatBuffersAllocated);
803
804    notify->setInt32("portIndex", portIndex);
805
806    sp<PortDescription> desc = new PortDescription;
807
808    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
809        const BufferInfo &info = mBuffers[portIndex][i];
810
811        desc->addBuffer(info.mBufferID, info.mData);
812    }
813
814    notify->setObject("portDesc", desc);
815    notify->post();
816
817    return OK;
818}
819
820status_t ACodec::setupNativeWindowSizeFormatAndUsage(ANativeWindow *nativeWindow /* nonnull */) {
821    OMX_PARAM_PORTDEFINITIONTYPE def;
822    InitOMXParams(&def);
823    def.nPortIndex = kPortIndexOutput;
824
825    status_t err = mOMX->getParameter(
826            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
827
828    if (err != OK) {
829        return err;
830    }
831
832    OMX_U32 usage = 0;
833    err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
834    if (err != 0) {
835        ALOGW("querying usage flags from OMX IL component failed: %d", err);
836        // XXX: Currently this error is logged, but not fatal.
837        usage = 0;
838    }
839    int omxUsage = usage;
840
841    if (mFlags & kFlagIsGrallocUsageProtected) {
842        usage |= GRALLOC_USAGE_PROTECTED;
843    }
844
845    usage |= GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP;
846
847    ALOGV("gralloc usage: %#x(OMX) => %#x(ACodec)", omxUsage, usage);
848    return setNativeWindowSizeFormatAndUsage(
849            nativeWindow,
850            def.format.video.nFrameWidth,
851            def.format.video.nFrameHeight,
852            def.format.video.eColorFormat,
853            mRotationDegrees,
854            usage);
855}
856
857status_t ACodec::configureOutputBuffersFromNativeWindow(
858        OMX_U32 *bufferCount, OMX_U32 *bufferSize,
859        OMX_U32 *minUndequeuedBuffers) {
860    OMX_PARAM_PORTDEFINITIONTYPE def;
861    InitOMXParams(&def);
862    def.nPortIndex = kPortIndexOutput;
863
864    status_t err = mOMX->getParameter(
865            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
866
867    if (err == OK) {
868        err = setupNativeWindowSizeFormatAndUsage(mNativeWindow.get());
869    }
870    if (err != OK) {
871        return err;
872    }
873
874    // Exits here for tunneled video playback codecs -- i.e. skips native window
875    // buffer allocation step as this is managed by the tunneled OMX omponent
876    // itself and explicitly sets def.nBufferCountActual to 0.
877    if (mTunneled) {
878        ALOGV("Tunneled Playback: skipping native window buffer allocation.");
879        def.nBufferCountActual = 0;
880        err = mOMX->setParameter(
881                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
882
883        *minUndequeuedBuffers = 0;
884        *bufferCount = 0;
885        *bufferSize = 0;
886        return err;
887    }
888
889    *minUndequeuedBuffers = 0;
890    err = mNativeWindow->query(
891            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
892            (int *)minUndequeuedBuffers);
893
894    if (err != 0) {
895        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
896                strerror(-err), -err);
897        return err;
898    }
899
900    // FIXME: assume that surface is controlled by app (native window
901    // returns the number for the case when surface is not controlled by app)
902    // FIXME2: This means that minUndeqeueudBufs can be 1 larger than reported
903    // For now, try to allocate 1 more buffer, but don't fail if unsuccessful
904
905    // Use conservative allocation while also trying to reduce starvation
906    //
907    // 1. allocate at least nBufferCountMin + minUndequeuedBuffers - that is the
908    //    minimum needed for the consumer to be able to work
909    // 2. try to allocate two (2) additional buffers to reduce starvation from
910    //    the consumer
911    //    plus an extra buffer to account for incorrect minUndequeuedBufs
912    for (OMX_U32 extraBuffers = 2 + 1; /* condition inside loop */; extraBuffers--) {
913        OMX_U32 newBufferCount =
914            def.nBufferCountMin + *minUndequeuedBuffers + extraBuffers;
915        def.nBufferCountActual = newBufferCount;
916        err = mOMX->setParameter(
917                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
918
919        if (err == OK) {
920            *minUndequeuedBuffers += extraBuffers;
921            break;
922        }
923
924        ALOGW("[%s] setting nBufferCountActual to %u failed: %d",
925                mComponentName.c_str(), newBufferCount, err);
926        /* exit condition */
927        if (extraBuffers == 0) {
928            return err;
929        }
930    }
931
932    err = native_window_set_buffer_count(
933            mNativeWindow.get(), def.nBufferCountActual);
934
935    if (err != 0) {
936        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
937                -err);
938        return err;
939    }
940
941    *bufferCount = def.nBufferCountActual;
942    *bufferSize =  def.nBufferSize;
943    return err;
944}
945
946status_t ACodec::allocateOutputBuffersFromNativeWindow() {
947    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
948    status_t err = configureOutputBuffersFromNativeWindow(
949            &bufferCount, &bufferSize, &minUndequeuedBuffers);
950    if (err != 0)
951        return err;
952    mNumUndequeuedBuffers = minUndequeuedBuffers;
953
954    if (!storingMetadataInDecodedBuffers()) {
955        static_cast<Surface*>(mNativeWindow.get())
956                ->getIGraphicBufferProducer()->allowAllocation(true);
957    }
958
959    ALOGV("[%s] Allocating %u buffers from a native window of size %u on "
960         "output port",
961         mComponentName.c_str(), bufferCount, bufferSize);
962
963    // Dequeue buffers and send them to OMX
964    for (OMX_U32 i = 0; i < bufferCount; i++) {
965        ANativeWindowBuffer *buf;
966        int fenceFd;
967        err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf, &fenceFd);
968        if (err != 0) {
969            ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
970            break;
971        }
972
973        sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
974        BufferInfo info;
975        info.mStatus = BufferInfo::OWNED_BY_US;
976        info.mFenceFd = fenceFd;
977        info.mIsReadFence = false;
978        info.mData = new ABuffer(NULL /* data */, bufferSize /* capacity */);
979        info.mGraphicBuffer = graphicBuffer;
980        mBuffers[kPortIndexOutput].push(info);
981
982        IOMX::buffer_id bufferId;
983        err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
984                &bufferId);
985        if (err != 0) {
986            ALOGE("registering GraphicBuffer %u with OMX IL component failed: "
987                 "%d", i, err);
988            break;
989        }
990
991        mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
992
993        ALOGV("[%s] Registered graphic buffer with ID %u (pointer = %p)",
994             mComponentName.c_str(),
995             bufferId, graphicBuffer.get());
996    }
997
998    OMX_U32 cancelStart;
999    OMX_U32 cancelEnd;
1000
1001    if (err != 0) {
1002        // If an error occurred while dequeuing we need to cancel any buffers
1003        // that were dequeued.
1004        cancelStart = 0;
1005        cancelEnd = mBuffers[kPortIndexOutput].size();
1006    } else {
1007        // Return the required minimum undequeued buffers to the native window.
1008        cancelStart = bufferCount - minUndequeuedBuffers;
1009        cancelEnd = bufferCount;
1010    }
1011
1012    for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
1013        BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
1014        status_t error = cancelBufferToNativeWindow(info);
1015        if (err == 0) {
1016            err = error;
1017        }
1018    }
1019
1020    if (!storingMetadataInDecodedBuffers()) {
1021        static_cast<Surface*>(mNativeWindow.get())
1022                ->getIGraphicBufferProducer()->allowAllocation(false);
1023    }
1024
1025    return err;
1026}
1027
1028status_t ACodec::allocateOutputMetadataBuffers() {
1029    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
1030    status_t err = configureOutputBuffersFromNativeWindow(
1031            &bufferCount, &bufferSize, &minUndequeuedBuffers);
1032    if (err != 0)
1033        return err;
1034    mNumUndequeuedBuffers = minUndequeuedBuffers;
1035
1036    ALOGV("[%s] Allocating %u meta buffers on output port",
1037         mComponentName.c_str(), bufferCount);
1038
1039    size_t bufSize = mOutputMetadataType == kMetadataBufferTypeANWBuffer ?
1040            sizeof(struct VideoNativeMetadata) : sizeof(struct VideoGrallocMetadata);
1041    size_t totalSize = bufferCount * bufSize;
1042    mDealer[kPortIndexOutput] = new MemoryDealer(totalSize, "ACodec");
1043
1044    // Dequeue buffers and send them to OMX
1045    for (OMX_U32 i = 0; i < bufferCount; i++) {
1046        BufferInfo info;
1047        info.mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
1048        info.mFenceFd = -1;
1049        info.mGraphicBuffer = NULL;
1050        info.mDequeuedAt = mDequeueCounter;
1051
1052        sp<IMemory> mem = mDealer[kPortIndexOutput]->allocate(bufSize);
1053        if (mem == NULL || mem->pointer() == NULL) {
1054            return NO_MEMORY;
1055        }
1056        if (mOutputMetadataType == kMetadataBufferTypeANWBuffer) {
1057            ((VideoNativeMetadata *)mem->pointer())->nFenceFd = -1;
1058        }
1059        info.mData = new ABuffer(mem->pointer(), mem->size());
1060
1061        // we use useBuffer for metadata regardless of quirks
1062        err = mOMX->useBuffer(
1063                mNode, kPortIndexOutput, mem, &info.mBufferID, mem->size());
1064
1065        mBuffers[kPortIndexOutput].push(info);
1066
1067        ALOGV("[%s] allocated meta buffer with ID %u (pointer = %p)",
1068             mComponentName.c_str(), info.mBufferID, mem->pointer());
1069    }
1070
1071    if (mLegacyAdaptiveExperiment) {
1072        // preallocate and preregister buffers
1073        static_cast<Surface *>(mNativeWindow.get())
1074                ->getIGraphicBufferProducer()->allowAllocation(true);
1075
1076        ALOGV("[%s] Allocating %u buffers from a native window of size %u on "
1077             "output port",
1078             mComponentName.c_str(), bufferCount, bufferSize);
1079
1080        // Dequeue buffers then cancel them all
1081        for (OMX_U32 i = 0; i < bufferCount; i++) {
1082            BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
1083
1084            ANativeWindowBuffer *buf;
1085            int fenceFd;
1086            err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf, &fenceFd);
1087            if (err != 0) {
1088                ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
1089                break;
1090            }
1091
1092            sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
1093            mOMX->updateGraphicBufferInMeta(
1094                    mNode, kPortIndexOutput, graphicBuffer, info->mBufferID);
1095            info->mStatus = BufferInfo::OWNED_BY_US;
1096            info->setWriteFence(fenceFd, "allocateOutputMetadataBuffers for legacy");
1097            info->mGraphicBuffer = graphicBuffer;
1098        }
1099
1100        for (OMX_U32 i = 0; i < mBuffers[kPortIndexOutput].size(); i++) {
1101            BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
1102            status_t error = cancelBufferToNativeWindow(info);
1103            if (err == OK) {
1104                err = error;
1105            }
1106        }
1107
1108        static_cast<Surface*>(mNativeWindow.get())
1109                ->getIGraphicBufferProducer()->allowAllocation(false);
1110    }
1111
1112    mMetadataBuffersToSubmit = bufferCount - minUndequeuedBuffers;
1113    return err;
1114}
1115
1116status_t ACodec::submitOutputMetadataBuffer() {
1117    CHECK(storingMetadataInDecodedBuffers());
1118    if (mMetadataBuffersToSubmit == 0)
1119        return OK;
1120
1121    BufferInfo *info = dequeueBufferFromNativeWindow();
1122    if (info == NULL) {
1123        return ERROR_IO;
1124    }
1125
1126    ALOGV("[%s] submitting output meta buffer ID %u for graphic buffer %p",
1127          mComponentName.c_str(), info->mBufferID, info->mGraphicBuffer.get());
1128
1129    --mMetadataBuffersToSubmit;
1130    info->checkWriteFence("submitOutputMetadataBuffer");
1131    status_t err = mOMX->fillBuffer(mNode, info->mBufferID, info->mFenceFd);
1132    info->mFenceFd = -1;
1133    if (err == OK) {
1134        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
1135    }
1136
1137    return err;
1138}
1139
1140status_t ACodec::waitForFence(int fd, const char *dbg ) {
1141    status_t res = OK;
1142    if (fd >= 0) {
1143        sp<Fence> fence = new Fence(fd);
1144        res = fence->wait(IOMX::kFenceTimeoutMs);
1145        ALOGW_IF(res != OK, "FENCE TIMEOUT for %d in %s", fd, dbg);
1146    }
1147    return res;
1148}
1149
1150// static
1151const char *ACodec::_asString(BufferInfo::Status s) {
1152    switch (s) {
1153        case BufferInfo::OWNED_BY_US:            return "OUR";
1154        case BufferInfo::OWNED_BY_COMPONENT:     return "COMPONENT";
1155        case BufferInfo::OWNED_BY_UPSTREAM:      return "UPSTREAM";
1156        case BufferInfo::OWNED_BY_DOWNSTREAM:    return "DOWNSTREAM";
1157        case BufferInfo::OWNED_BY_NATIVE_WINDOW: return "SURFACE";
1158        case BufferInfo::UNRECOGNIZED:           return "UNRECOGNIZED";
1159        default:                                 return "?";
1160    }
1161}
1162
1163void ACodec::dumpBuffers(OMX_U32 portIndex) {
1164    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
1165    ALOGI("[%s] %s port has %zu buffers:", mComponentName.c_str(),
1166            portIndex == kPortIndexInput ? "input" : "output", mBuffers[portIndex].size());
1167    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
1168        const BufferInfo &info = mBuffers[portIndex][i];
1169        ALOGI("  slot %2zu: #%8u %p/%p %s(%d) dequeued:%u",
1170                i, info.mBufferID, info.mGraphicBuffer.get(),
1171                info.mGraphicBuffer == NULL ? NULL : info.mGraphicBuffer->getNativeBuffer(),
1172                _asString(info.mStatus), info.mStatus, info.mDequeuedAt);
1173    }
1174}
1175
1176status_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
1177    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
1178
1179    ALOGV("[%s] Calling cancelBuffer on buffer %u",
1180         mComponentName.c_str(), info->mBufferID);
1181
1182    info->checkWriteFence("cancelBufferToNativeWindow");
1183    int err = mNativeWindow->cancelBuffer(
1184        mNativeWindow.get(), info->mGraphicBuffer.get(), info->mFenceFd);
1185    info->mFenceFd = -1;
1186
1187    ALOGW_IF(err != 0, "[%s] can not return buffer %u to native window",
1188            mComponentName.c_str(), info->mBufferID);
1189    // change ownership even if cancelBuffer fails
1190    info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
1191
1192    return err;
1193}
1194
1195ACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
1196    ANativeWindowBuffer *buf;
1197    CHECK(mNativeWindow.get() != NULL);
1198
1199    if (mTunneled) {
1200        ALOGW("dequeueBufferFromNativeWindow() should not be called in tunnel"
1201              " video playback mode mode!");
1202        return NULL;
1203    }
1204
1205    int fenceFd = -1;
1206    do {
1207        status_t err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf, &fenceFd);
1208        if (err != 0) {
1209            ALOGE("dequeueBuffer failed: %s(%d).", asString(err), err);
1210            return NULL;
1211        }
1212
1213        bool stale = false;
1214        for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
1215            BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
1216
1217            if (info->mGraphicBuffer != NULL &&
1218                info->mGraphicBuffer->handle == buf->handle) {
1219                // Since consumers can attach buffers to BufferQueues, it is possible
1220                // that a known yet stale buffer can return from a surface that we
1221                // once used.  We can simply ignore this as we have already dequeued
1222                // this buffer properly.  NOTE: this does not eliminate all cases,
1223                // e.g. it is possible that we have queued the valid buffer to the
1224                // NW, and a stale copy of the same buffer gets dequeued - which will
1225                // be treated as the valid buffer by ACodec.
1226                if (info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
1227                    ALOGI("dequeued stale buffer %p. discarding", buf);
1228                    stale = true;
1229                    break;
1230                }
1231                ALOGV("dequeued buffer %p", info->mGraphicBuffer->getNativeBuffer());
1232                info->mStatus = BufferInfo::OWNED_BY_US;
1233                info->setWriteFence(fenceFd, "dequeueBufferFromNativeWindow");
1234                return info;
1235            }
1236        }
1237
1238        // It is also possible to receive a previously unregistered buffer
1239        // in non-meta mode. These should be treated as stale buffers. The
1240        // same is possible in meta mode, in which case, it will be treated
1241        // as a normal buffer, which is not desirable.
1242        // TODO: fix this.
1243        if (!stale && (!storingMetadataInDecodedBuffers() || mLegacyAdaptiveExperiment)) {
1244            ALOGI("dequeued unrecognized (stale) buffer %p. discarding", buf);
1245            stale = true;
1246        }
1247        if (stale) {
1248            // TODO: detach stale buffer, but there is no API yet to do it.
1249            buf = NULL;
1250        }
1251    } while (buf == NULL);
1252
1253    // get oldest undequeued buffer
1254    BufferInfo *oldest = NULL;
1255    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
1256        BufferInfo *info =
1257            &mBuffers[kPortIndexOutput].editItemAt(i);
1258        if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW &&
1259            (oldest == NULL ||
1260             // avoid potential issues from counter rolling over
1261             mDequeueCounter - info->mDequeuedAt >
1262                    mDequeueCounter - oldest->mDequeuedAt)) {
1263            oldest = info;
1264        }
1265    }
1266
1267    // it is impossible dequeue a buffer when there are no buffers with ANW
1268    CHECK(oldest != NULL);
1269    // it is impossible to dequeue an unknown buffer in non-meta mode, as the
1270    // while loop above does not complete
1271    CHECK(storingMetadataInDecodedBuffers());
1272
1273    // discard buffer in LRU info and replace with new buffer
1274    oldest->mGraphicBuffer = new GraphicBuffer(buf, false);
1275    oldest->mStatus = BufferInfo::OWNED_BY_US;
1276    oldest->setWriteFence(fenceFd, "dequeueBufferFromNativeWindow for oldest");
1277
1278    mOMX->updateGraphicBufferInMeta(
1279            mNode, kPortIndexOutput, oldest->mGraphicBuffer,
1280            oldest->mBufferID);
1281
1282    if (mOutputMetadataType == kMetadataBufferTypeGrallocSource) {
1283        VideoGrallocMetadata *grallocMeta =
1284            reinterpret_cast<VideoGrallocMetadata *>(oldest->mData->base());
1285        ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
1286                (unsigned)(oldest - &mBuffers[kPortIndexOutput][0]),
1287                mDequeueCounter - oldest->mDequeuedAt,
1288                grallocMeta->pHandle,
1289                oldest->mGraphicBuffer->handle, oldest->mData->base());
1290    } else if (mOutputMetadataType == kMetadataBufferTypeANWBuffer) {
1291        VideoNativeMetadata *nativeMeta =
1292            reinterpret_cast<VideoNativeMetadata *>(oldest->mData->base());
1293        ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
1294                (unsigned)(oldest - &mBuffers[kPortIndexOutput][0]),
1295                mDequeueCounter - oldest->mDequeuedAt,
1296                nativeMeta->pBuffer,
1297                oldest->mGraphicBuffer->getNativeBuffer(), oldest->mData->base());
1298    }
1299
1300    return oldest;
1301}
1302
1303status_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
1304    status_t err = OK;
1305    for (size_t i = mBuffers[portIndex].size(); i-- > 0;) {
1306        status_t err2 = freeBuffer(portIndex, i);
1307        if (err == OK) {
1308            err = err2;
1309        }
1310    }
1311
1312    // clear mDealer even on an error
1313    mDealer[portIndex].clear();
1314    return err;
1315}
1316
1317status_t ACodec::freeOutputBuffersNotOwnedByComponent() {
1318    status_t err = OK;
1319    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
1320        BufferInfo *info =
1321            &mBuffers[kPortIndexOutput].editItemAt(i);
1322
1323        // At this time some buffers may still be with the component
1324        // or being drained.
1325        if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT &&
1326            info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) {
1327            status_t err2 = freeBuffer(kPortIndexOutput, i);
1328            if (err == OK) {
1329                err = err2;
1330            }
1331        }
1332    }
1333
1334    return err;
1335}
1336
1337status_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
1338    BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
1339    status_t err = OK;
1340
1341    // there should not be any fences in the metadata
1342    MetadataBufferType type =
1343        portIndex == kPortIndexOutput ? mOutputMetadataType : mInputMetadataType;
1344    if (type == kMetadataBufferTypeANWBuffer && info->mData != NULL
1345            && info->mData->size() >= sizeof(VideoNativeMetadata)) {
1346        int fenceFd = ((VideoNativeMetadata *)info->mData->data())->nFenceFd;
1347        if (fenceFd >= 0) {
1348            ALOGW("unreleased fence (%d) in %s metadata buffer %zu",
1349                    fenceFd, portIndex == kPortIndexInput ? "input" : "output", i);
1350        }
1351    }
1352
1353    switch (info->mStatus) {
1354        case BufferInfo::OWNED_BY_US:
1355            if (portIndex == kPortIndexOutput && mNativeWindow != NULL) {
1356                (void)cancelBufferToNativeWindow(info);
1357            }
1358            // fall through
1359
1360        case BufferInfo::OWNED_BY_NATIVE_WINDOW:
1361            err = mOMX->freeBuffer(mNode, portIndex, info->mBufferID);
1362            break;
1363
1364        default:
1365            ALOGE("trying to free buffer not owned by us or ANW (%d)", info->mStatus);
1366            err = FAILED_TRANSACTION;
1367            break;
1368    }
1369
1370    if (info->mFenceFd >= 0) {
1371        ::close(info->mFenceFd);
1372    }
1373
1374    // remove buffer even if mOMX->freeBuffer fails
1375    mBuffers[portIndex].removeAt(i);
1376
1377    return err;
1378}
1379
1380ACodec::BufferInfo *ACodec::findBufferByID(
1381        uint32_t portIndex, IOMX::buffer_id bufferID, ssize_t *index) {
1382    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
1383        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
1384
1385        if (info->mBufferID == bufferID) {
1386            if (index != NULL) {
1387                *index = i;
1388            }
1389            return info;
1390        }
1391    }
1392
1393    ALOGE("Could not find buffer with ID %u", bufferID);
1394    return NULL;
1395}
1396
1397status_t ACodec::setComponentRole(
1398        bool isEncoder, const char *mime) {
1399    struct MimeToRole {
1400        const char *mime;
1401        const char *decoderRole;
1402        const char *encoderRole;
1403    };
1404
1405    static const MimeToRole kMimeToRole[] = {
1406        { MEDIA_MIMETYPE_AUDIO_MPEG,
1407            "audio_decoder.mp3", "audio_encoder.mp3" },
1408        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
1409            "audio_decoder.mp1", "audio_encoder.mp1" },
1410        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
1411            "audio_decoder.mp2", "audio_encoder.mp2" },
1412        { MEDIA_MIMETYPE_AUDIO_AMR_NB,
1413            "audio_decoder.amrnb", "audio_encoder.amrnb" },
1414        { MEDIA_MIMETYPE_AUDIO_AMR_WB,
1415            "audio_decoder.amrwb", "audio_encoder.amrwb" },
1416        { MEDIA_MIMETYPE_AUDIO_AAC,
1417            "audio_decoder.aac", "audio_encoder.aac" },
1418        { MEDIA_MIMETYPE_AUDIO_VORBIS,
1419            "audio_decoder.vorbis", "audio_encoder.vorbis" },
1420        { MEDIA_MIMETYPE_AUDIO_OPUS,
1421            "audio_decoder.opus", "audio_encoder.opus" },
1422        { MEDIA_MIMETYPE_AUDIO_G711_MLAW,
1423            "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" },
1424        { MEDIA_MIMETYPE_AUDIO_G711_ALAW,
1425            "audio_decoder.g711alaw", "audio_encoder.g711alaw" },
1426        { MEDIA_MIMETYPE_VIDEO_AVC,
1427            "video_decoder.avc", "video_encoder.avc" },
1428        { MEDIA_MIMETYPE_VIDEO_HEVC,
1429            "video_decoder.hevc", "video_encoder.hevc" },
1430        { MEDIA_MIMETYPE_VIDEO_MPEG4,
1431            "video_decoder.mpeg4", "video_encoder.mpeg4" },
1432        { MEDIA_MIMETYPE_VIDEO_H263,
1433            "video_decoder.h263", "video_encoder.h263" },
1434        { MEDIA_MIMETYPE_VIDEO_VP8,
1435            "video_decoder.vp8", "video_encoder.vp8" },
1436        { MEDIA_MIMETYPE_VIDEO_VP9,
1437            "video_decoder.vp9", "video_encoder.vp9" },
1438        { MEDIA_MIMETYPE_AUDIO_RAW,
1439            "audio_decoder.raw", "audio_encoder.raw" },
1440        { MEDIA_MIMETYPE_AUDIO_FLAC,
1441            "audio_decoder.flac", "audio_encoder.flac" },
1442        { MEDIA_MIMETYPE_AUDIO_MSGSM,
1443            "audio_decoder.gsm", "audio_encoder.gsm" },
1444        { MEDIA_MIMETYPE_VIDEO_MPEG2,
1445            "video_decoder.mpeg2", "video_encoder.mpeg2" },
1446        { MEDIA_MIMETYPE_AUDIO_AC3,
1447            "audio_decoder.ac3", "audio_encoder.ac3" },
1448        { MEDIA_MIMETYPE_AUDIO_EAC3,
1449            "audio_decoder.eac3", "audio_encoder.eac3" },
1450    };
1451
1452    static const size_t kNumMimeToRole =
1453        sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
1454
1455    size_t i;
1456    for (i = 0; i < kNumMimeToRole; ++i) {
1457        if (!strcasecmp(mime, kMimeToRole[i].mime)) {
1458            break;
1459        }
1460    }
1461
1462    if (i == kNumMimeToRole) {
1463        return ERROR_UNSUPPORTED;
1464    }
1465
1466    const char *role =
1467        isEncoder ? kMimeToRole[i].encoderRole
1468                  : kMimeToRole[i].decoderRole;
1469
1470    if (role != NULL) {
1471        OMX_PARAM_COMPONENTROLETYPE roleParams;
1472        InitOMXParams(&roleParams);
1473
1474        strncpy((char *)roleParams.cRole,
1475                role, OMX_MAX_STRINGNAME_SIZE - 1);
1476
1477        roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
1478
1479        status_t err = mOMX->setParameter(
1480                mNode, OMX_IndexParamStandardComponentRole,
1481                &roleParams, sizeof(roleParams));
1482
1483        if (err != OK) {
1484            ALOGW("[%s] Failed to set standard component role '%s'.",
1485                 mComponentName.c_str(), role);
1486
1487            return err;
1488        }
1489    }
1490
1491    return OK;
1492}
1493
1494status_t ACodec::configureCodec(
1495        const char *mime, const sp<AMessage> &msg) {
1496    int32_t encoder;
1497    if (!msg->findInt32("encoder", &encoder)) {
1498        encoder = false;
1499    }
1500
1501    sp<AMessage> inputFormat = new AMessage();
1502    sp<AMessage> outputFormat = mNotify->dup(); // will use this for kWhatOutputFormatChanged
1503
1504    mIsEncoder = encoder;
1505
1506    mInputMetadataType = kMetadataBufferTypeInvalid;
1507    mOutputMetadataType = kMetadataBufferTypeInvalid;
1508
1509    status_t err = setComponentRole(encoder /* isEncoder */, mime);
1510
1511    if (err != OK) {
1512        return err;
1513    }
1514
1515    int32_t bitRate = 0;
1516    // FLAC encoder doesn't need a bitrate, other encoders do
1517    if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
1518            && !msg->findInt32("bitrate", &bitRate)) {
1519        return INVALID_OPERATION;
1520    }
1521
1522    int32_t storeMeta;
1523    if (encoder
1524            && msg->findInt32("store-metadata-in-buffers", &storeMeta)
1525            && storeMeta != 0) {
1526        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE, &mInputMetadataType);
1527        if (err != OK) {
1528            ALOGE("[%s] storeMetaDataInBuffers (input) failed w/ err %d",
1529                    mComponentName.c_str(), err);
1530
1531            return err;
1532        }
1533        // For this specific case we could be using camera source even if storeMetaDataInBuffers
1534        // returns Gralloc source. Pretend that we are; this will force us to use nBufferSize.
1535        if (mInputMetadataType == kMetadataBufferTypeGrallocSource) {
1536            mInputMetadataType = kMetadataBufferTypeCameraSource;
1537        }
1538    }
1539
1540    int32_t prependSPSPPS = 0;
1541    if (encoder
1542            && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
1543            && prependSPSPPS != 0) {
1544        OMX_INDEXTYPE index;
1545        err = mOMX->getExtensionIndex(
1546                mNode,
1547                "OMX.google.android.index.prependSPSPPSToIDRFrames",
1548                &index);
1549
1550        if (err == OK) {
1551            PrependSPSPPSToIDRFramesParams params;
1552            InitOMXParams(&params);
1553            params.bEnable = OMX_TRUE;
1554
1555            err = mOMX->setParameter(
1556                    mNode, index, &params, sizeof(params));
1557        }
1558
1559        if (err != OK) {
1560            ALOGE("Encoder could not be configured to emit SPS/PPS before "
1561                  "IDR frames. (err %d)", err);
1562
1563            return err;
1564        }
1565    }
1566
1567    // Only enable metadata mode on encoder output if encoder can prepend
1568    // sps/pps to idr frames, since in metadata mode the bitstream is in an
1569    // opaque handle, to which we don't have access.
1570    int32_t video = !strncasecmp(mime, "video/", 6);
1571    mIsVideo = video;
1572    if (encoder && video) {
1573        OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS
1574            && msg->findInt32("store-metadata-in-buffers-output", &storeMeta)
1575            && storeMeta != 0);
1576
1577        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, enable, &mOutputMetadataType);
1578        if (err != OK) {
1579            ALOGE("[%s] storeMetaDataInBuffers (output) failed w/ err %d",
1580                mComponentName.c_str(), err);
1581        }
1582
1583        if (!msg->findInt64(
1584                    "repeat-previous-frame-after",
1585                    &mRepeatFrameDelayUs)) {
1586            mRepeatFrameDelayUs = -1ll;
1587        }
1588
1589        if (!msg->findInt64("max-pts-gap-to-encoder", &mMaxPtsGapUs)) {
1590            mMaxPtsGapUs = -1ll;
1591        }
1592
1593        if (!msg->findFloat("max-fps-to-encoder", &mMaxFps)) {
1594            mMaxFps = -1;
1595        }
1596
1597        if (!msg->findInt64("time-lapse", &mTimePerCaptureUs)) {
1598            mTimePerCaptureUs = -1ll;
1599        }
1600
1601        if (!msg->findInt32(
1602                    "create-input-buffers-suspended",
1603                    (int32_t*)&mCreateInputBuffersSuspended)) {
1604            mCreateInputBuffersSuspended = false;
1605        }
1606    }
1607
1608    // NOTE: we only use native window for video decoders
1609    sp<RefBase> obj;
1610    bool haveNativeWindow = msg->findObject("native-window", &obj)
1611            && obj != NULL && video && !encoder;
1612    mLegacyAdaptiveExperiment = false;
1613    if (video && !encoder) {
1614        inputFormat->setInt32("adaptive-playback", false);
1615
1616        int32_t usageProtected;
1617        if (msg->findInt32("protected", &usageProtected) && usageProtected) {
1618            if (!haveNativeWindow) {
1619                ALOGE("protected output buffers must be sent to an ANativeWindow");
1620                return PERMISSION_DENIED;
1621            }
1622            mFlags |= kFlagIsGrallocUsageProtected;
1623            mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
1624        }
1625    }
1626    if (haveNativeWindow) {
1627        sp<ANativeWindow> nativeWindow =
1628            static_cast<ANativeWindow *>(static_cast<Surface *>(obj.get()));
1629
1630        // START of temporary support for automatic FRC - THIS WILL BE REMOVED
1631        int32_t autoFrc;
1632        if (msg->findInt32("auto-frc", &autoFrc)) {
1633            bool enabled = autoFrc;
1634            OMX_CONFIG_BOOLEANTYPE config;
1635            InitOMXParams(&config);
1636            config.bEnabled = (OMX_BOOL)enabled;
1637            status_t temp = mOMX->setConfig(
1638                    mNode, (OMX_INDEXTYPE)OMX_IndexConfigAutoFramerateConversion,
1639                    &config, sizeof(config));
1640            if (temp == OK) {
1641                outputFormat->setInt32("auto-frc", enabled);
1642            } else if (enabled) {
1643                ALOGI("codec does not support requested auto-frc (err %d)", temp);
1644            }
1645        }
1646        // END of temporary support for automatic FRC
1647
1648        int32_t tunneled;
1649        if (msg->findInt32("feature-tunneled-playback", &tunneled) &&
1650            tunneled != 0) {
1651            ALOGI("Configuring TUNNELED video playback.");
1652            mTunneled = true;
1653
1654            int32_t audioHwSync = 0;
1655            if (!msg->findInt32("audio-hw-sync", &audioHwSync)) {
1656                ALOGW("No Audio HW Sync provided for video tunnel");
1657            }
1658            err = configureTunneledVideoPlayback(audioHwSync, nativeWindow);
1659            if (err != OK) {
1660                ALOGE("configureTunneledVideoPlayback(%d,%p) failed!",
1661                        audioHwSync, nativeWindow.get());
1662                return err;
1663            }
1664
1665            int32_t maxWidth = 0, maxHeight = 0;
1666            if (msg->findInt32("max-width", &maxWidth) &&
1667                    msg->findInt32("max-height", &maxHeight)) {
1668
1669                err = mOMX->prepareForAdaptivePlayback(
1670                        mNode, kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight);
1671                if (err != OK) {
1672                    ALOGW("[%s] prepareForAdaptivePlayback failed w/ err %d",
1673                            mComponentName.c_str(), err);
1674                    // allow failure
1675                    err = OK;
1676                } else {
1677                    inputFormat->setInt32("max-width", maxWidth);
1678                    inputFormat->setInt32("max-height", maxHeight);
1679                    inputFormat->setInt32("adaptive-playback", true);
1680                }
1681            }
1682        } else {
1683            ALOGV("Configuring CPU controlled video playback.");
1684            mTunneled = false;
1685
1686            // Explicity reset the sideband handle of the window for
1687            // non-tunneled video in case the window was previously used
1688            // for a tunneled video playback.
1689            err = native_window_set_sideband_stream(nativeWindow.get(), NULL);
1690            if (err != OK) {
1691                ALOGE("set_sideband_stream(NULL) failed! (err %d).", err);
1692                return err;
1693            }
1694
1695            // Always try to enable dynamic output buffers on native surface
1696            err = mOMX->storeMetaDataInBuffers(
1697                    mNode, kPortIndexOutput, OMX_TRUE, &mOutputMetadataType);
1698            if (err != OK) {
1699                ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d",
1700                        mComponentName.c_str(), err);
1701
1702                // if adaptive playback has been requested, try JB fallback
1703                // NOTE: THIS FALLBACK MECHANISM WILL BE REMOVED DUE TO ITS
1704                // LARGE MEMORY REQUIREMENT
1705
1706                // we will not do adaptive playback on software accessed
1707                // surfaces as they never had to respond to changes in the
1708                // crop window, and we don't trust that they will be able to.
1709                int usageBits = 0;
1710                bool canDoAdaptivePlayback;
1711
1712                if (nativeWindow->query(
1713                        nativeWindow.get(),
1714                        NATIVE_WINDOW_CONSUMER_USAGE_BITS,
1715                        &usageBits) != OK) {
1716                    canDoAdaptivePlayback = false;
1717                } else {
1718                    canDoAdaptivePlayback =
1719                        (usageBits &
1720                                (GRALLOC_USAGE_SW_READ_MASK |
1721                                 GRALLOC_USAGE_SW_WRITE_MASK)) == 0;
1722                }
1723
1724                int32_t maxWidth = 0, maxHeight = 0;
1725                if (canDoAdaptivePlayback &&
1726                        msg->findInt32("max-width", &maxWidth) &&
1727                        msg->findInt32("max-height", &maxHeight)) {
1728                    ALOGV("[%s] prepareForAdaptivePlayback(%dx%d)",
1729                            mComponentName.c_str(), maxWidth, maxHeight);
1730
1731                    err = mOMX->prepareForAdaptivePlayback(
1732                            mNode, kPortIndexOutput, OMX_TRUE, maxWidth,
1733                            maxHeight);
1734                    ALOGW_IF(err != OK,
1735                            "[%s] prepareForAdaptivePlayback failed w/ err %d",
1736                            mComponentName.c_str(), err);
1737
1738                    if (err == OK) {
1739                        inputFormat->setInt32("max-width", maxWidth);
1740                        inputFormat->setInt32("max-height", maxHeight);
1741                        inputFormat->setInt32("adaptive-playback", true);
1742                    }
1743                }
1744                // allow failure
1745                err = OK;
1746            } else {
1747                ALOGV("[%s] storeMetaDataInBuffers succeeded",
1748                        mComponentName.c_str());
1749                CHECK(storingMetadataInDecodedBuffers());
1750                mLegacyAdaptiveExperiment = ADebug::isExperimentEnabled(
1751                        "legacy-adaptive", !msg->contains("no-experiments"));
1752
1753                inputFormat->setInt32("adaptive-playback", true);
1754            }
1755
1756            int32_t push;
1757            if (msg->findInt32("push-blank-buffers-on-shutdown", &push)
1758                    && push != 0) {
1759                mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
1760            }
1761        }
1762
1763        int32_t rotationDegrees;
1764        if (msg->findInt32("rotation-degrees", &rotationDegrees)) {
1765            mRotationDegrees = rotationDegrees;
1766        } else {
1767            mRotationDegrees = 0;
1768        }
1769    }
1770
1771    if (video) {
1772        // determine need for software renderer
1773        bool usingSwRenderer = false;
1774        if (haveNativeWindow && mComponentName.startsWith("OMX.google.")) {
1775            usingSwRenderer = true;
1776            haveNativeWindow = false;
1777        }
1778
1779        if (encoder) {
1780            err = setupVideoEncoder(mime, msg);
1781        } else {
1782            err = setupVideoDecoder(mime, msg, haveNativeWindow);
1783        }
1784
1785        if (err != OK) {
1786            return err;
1787        }
1788
1789        if (haveNativeWindow) {
1790            mNativeWindow = static_cast<Surface *>(obj.get());
1791        }
1792
1793        // initialize native window now to get actual output format
1794        // TODO: this is needed for some encoders even though they don't use native window
1795        err = initNativeWindow();
1796        if (err != OK) {
1797            return err;
1798        }
1799
1800        // fallback for devices that do not handle flex-YUV for native buffers
1801        if (haveNativeWindow) {
1802            int32_t requestedColorFormat = OMX_COLOR_FormatUnused;
1803            if (msg->findInt32("color-format", &requestedColorFormat) &&
1804                    requestedColorFormat == OMX_COLOR_FormatYUV420Flexible) {
1805                status_t err = getPortFormat(kPortIndexOutput, outputFormat);
1806                if (err != OK) {
1807                    return err;
1808                }
1809                int32_t colorFormat = OMX_COLOR_FormatUnused;
1810                OMX_U32 flexibleEquivalent = OMX_COLOR_FormatUnused;
1811                if (!outputFormat->findInt32("color-format", &colorFormat)) {
1812                    ALOGE("ouptut port did not have a color format (wrong domain?)");
1813                    return BAD_VALUE;
1814                }
1815                ALOGD("[%s] Requested output format %#x and got %#x.",
1816                        mComponentName.c_str(), requestedColorFormat, colorFormat);
1817                if (!isFlexibleColorFormat(
1818                                mOMX, mNode, colorFormat, haveNativeWindow, &flexibleEquivalent)
1819                        || flexibleEquivalent != (OMX_U32)requestedColorFormat) {
1820                    // device did not handle flex-YUV request for native window, fall back
1821                    // to SW renderer
1822                    ALOGI("[%s] Falling back to software renderer", mComponentName.c_str());
1823                    mNativeWindow.clear();
1824                    haveNativeWindow = false;
1825                    usingSwRenderer = true;
1826                    if (storingMetadataInDecodedBuffers()) {
1827                        err = mOMX->storeMetaDataInBuffers(
1828                                mNode, kPortIndexOutput, OMX_FALSE, &mOutputMetadataType);
1829                        mOutputMetadataType = kMetadataBufferTypeInvalid; // just in case
1830                        // TODO: implement adaptive-playback support for bytebuffer mode.
1831                        // This is done by SW codecs, but most HW codecs don't support it.
1832                        inputFormat->setInt32("adaptive-playback", false);
1833                    }
1834                    if (err == OK) {
1835                        err = mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
1836                    }
1837                    if (mFlags & kFlagIsGrallocUsageProtected) {
1838                        // fallback is not supported for protected playback
1839                        err = PERMISSION_DENIED;
1840                    } else if (err == OK) {
1841                        err = setupVideoDecoder(mime, msg, false);
1842                    }
1843                }
1844            }
1845        }
1846
1847        if (usingSwRenderer) {
1848            outputFormat->setInt32("using-sw-renderer", 1);
1849        }
1850    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
1851        int32_t numChannels, sampleRate;
1852        if (!msg->findInt32("channel-count", &numChannels)
1853                || !msg->findInt32("sample-rate", &sampleRate)) {
1854            // Since we did not always check for these, leave them optional
1855            // and have the decoder figure it all out.
1856            err = OK;
1857        } else {
1858            err = setupRawAudioFormat(
1859                    encoder ? kPortIndexInput : kPortIndexOutput,
1860                    sampleRate,
1861                    numChannels);
1862        }
1863    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
1864        int32_t numChannels, sampleRate;
1865        if (!msg->findInt32("channel-count", &numChannels)
1866                || !msg->findInt32("sample-rate", &sampleRate)) {
1867            err = INVALID_OPERATION;
1868        } else {
1869            int32_t isADTS, aacProfile;
1870            int32_t sbrMode;
1871            int32_t maxOutputChannelCount;
1872            int32_t pcmLimiterEnable;
1873            drcParams_t drc;
1874            if (!msg->findInt32("is-adts", &isADTS)) {
1875                isADTS = 0;
1876            }
1877            if (!msg->findInt32("aac-profile", &aacProfile)) {
1878                aacProfile = OMX_AUDIO_AACObjectNull;
1879            }
1880            if (!msg->findInt32("aac-sbr-mode", &sbrMode)) {
1881                sbrMode = -1;
1882            }
1883
1884            if (!msg->findInt32("aac-max-output-channel_count", &maxOutputChannelCount)) {
1885                maxOutputChannelCount = -1;
1886            }
1887            if (!msg->findInt32("aac-pcm-limiter-enable", &pcmLimiterEnable)) {
1888                // value is unknown
1889                pcmLimiterEnable = -1;
1890            }
1891            if (!msg->findInt32("aac-encoded-target-level", &drc.encodedTargetLevel)) {
1892                // value is unknown
1893                drc.encodedTargetLevel = -1;
1894            }
1895            if (!msg->findInt32("aac-drc-cut-level", &drc.drcCut)) {
1896                // value is unknown
1897                drc.drcCut = -1;
1898            }
1899            if (!msg->findInt32("aac-drc-boost-level", &drc.drcBoost)) {
1900                // value is unknown
1901                drc.drcBoost = -1;
1902            }
1903            if (!msg->findInt32("aac-drc-heavy-compression", &drc.heavyCompression)) {
1904                // value is unknown
1905                drc.heavyCompression = -1;
1906            }
1907            if (!msg->findInt32("aac-target-ref-level", &drc.targetRefLevel)) {
1908                // value is unknown
1909                drc.targetRefLevel = -1;
1910            }
1911
1912            err = setupAACCodec(
1913                    encoder, numChannels, sampleRate, bitRate, aacProfile,
1914                    isADTS != 0, sbrMode, maxOutputChannelCount, drc,
1915                    pcmLimiterEnable);
1916        }
1917    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
1918        err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
1919    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
1920        err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
1921    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
1922            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
1923        // These are PCM-like formats with a fixed sample rate but
1924        // a variable number of channels.
1925
1926        int32_t numChannels;
1927        if (!msg->findInt32("channel-count", &numChannels)) {
1928            err = INVALID_OPERATION;
1929        } else {
1930            int32_t sampleRate;
1931            if (!msg->findInt32("sample-rate", &sampleRate)) {
1932                sampleRate = 8000;
1933            }
1934            err = setupG711Codec(encoder, sampleRate, numChannels);
1935        }
1936    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
1937        int32_t numChannels = 0, sampleRate = 0, compressionLevel = -1;
1938        if (encoder &&
1939                (!msg->findInt32("channel-count", &numChannels)
1940                        || !msg->findInt32("sample-rate", &sampleRate))) {
1941            ALOGE("missing channel count or sample rate for FLAC encoder");
1942            err = INVALID_OPERATION;
1943        } else {
1944            if (encoder) {
1945                if (!msg->findInt32(
1946                            "complexity", &compressionLevel) &&
1947                    !msg->findInt32(
1948                            "flac-compression-level", &compressionLevel)) {
1949                    compressionLevel = 5; // default FLAC compression level
1950                } else if (compressionLevel < 0) {
1951                    ALOGW("compression level %d outside [0..8] range, "
1952                          "using 0",
1953                          compressionLevel);
1954                    compressionLevel = 0;
1955                } else if (compressionLevel > 8) {
1956                    ALOGW("compression level %d outside [0..8] range, "
1957                          "using 8",
1958                          compressionLevel);
1959                    compressionLevel = 8;
1960                }
1961            }
1962            err = setupFlacCodec(
1963                    encoder, numChannels, sampleRate, compressionLevel);
1964        }
1965    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
1966        int32_t numChannels, sampleRate;
1967        if (encoder
1968                || !msg->findInt32("channel-count", &numChannels)
1969                || !msg->findInt32("sample-rate", &sampleRate)) {
1970            err = INVALID_OPERATION;
1971        } else {
1972            err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
1973        }
1974    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AC3)) {
1975        int32_t numChannels;
1976        int32_t sampleRate;
1977        if (!msg->findInt32("channel-count", &numChannels)
1978                || !msg->findInt32("sample-rate", &sampleRate)) {
1979            err = INVALID_OPERATION;
1980        } else {
1981            err = setupAC3Codec(encoder, numChannels, sampleRate);
1982        }
1983    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_EAC3)) {
1984        int32_t numChannels;
1985        int32_t sampleRate;
1986        if (!msg->findInt32("channel-count", &numChannels)
1987                || !msg->findInt32("sample-rate", &sampleRate)) {
1988            err = INVALID_OPERATION;
1989        } else {
1990            err = setupEAC3Codec(encoder, numChannels, sampleRate);
1991        }
1992    }
1993
1994    if (err != OK) {
1995        return err;
1996    }
1997
1998    if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
1999        mEncoderDelay = 0;
2000    }
2001
2002    if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
2003        mEncoderPadding = 0;
2004    }
2005
2006    if (msg->findInt32("channel-mask", &mChannelMask)) {
2007        mChannelMaskPresent = true;
2008    } else {
2009        mChannelMaskPresent = false;
2010    }
2011
2012    int32_t maxInputSize;
2013    if (msg->findInt32("max-input-size", &maxInputSize)) {
2014        err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
2015    } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
2016        err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
2017    }
2018
2019    int32_t priority;
2020    if (msg->findInt32("priority", &priority)) {
2021        err = setPriority(priority);
2022    }
2023
2024    int32_t rateInt = -1;
2025    float rateFloat = -1;
2026    if (!msg->findFloat("operating-rate", &rateFloat)) {
2027        msg->findInt32("operating-rate", &rateInt);
2028        rateFloat = (float)rateInt;  // 16MHz (FLINTMAX) is OK for upper bound.
2029    }
2030    if (rateFloat > 0) {
2031        err = setOperatingRate(rateFloat, video);
2032    }
2033
2034    mBaseOutputFormat = outputFormat;
2035
2036    err = getPortFormat(kPortIndexInput, inputFormat);
2037    if (err == OK) {
2038        err = getPortFormat(kPortIndexOutput, outputFormat);
2039        if (err == OK) {
2040            mInputFormat = inputFormat;
2041            mOutputFormat = outputFormat;
2042        }
2043    }
2044    return err;
2045}
2046
2047status_t ACodec::setPriority(int32_t priority) {
2048    if (priority < 0) {
2049        return BAD_VALUE;
2050    }
2051    OMX_PARAM_U32TYPE config;
2052    InitOMXParams(&config);
2053    config.nU32 = (OMX_U32)priority;
2054    status_t temp = mOMX->setConfig(
2055            mNode, (OMX_INDEXTYPE)OMX_IndexConfigPriority,
2056            &config, sizeof(config));
2057    if (temp != OK) {
2058        ALOGI("codec does not support config priority (err %d)", temp);
2059    }
2060    return OK;
2061}
2062
2063status_t ACodec::setOperatingRate(float rateFloat, bool isVideo) {
2064    if (rateFloat < 0) {
2065        return BAD_VALUE;
2066    }
2067    OMX_U32 rate;
2068    if (isVideo) {
2069        if (rateFloat > 65535) {
2070            return BAD_VALUE;
2071        }
2072        rate = (OMX_U32)(rateFloat * 65536.0f + 0.5f);
2073    } else {
2074        if (rateFloat > UINT_MAX) {
2075            return BAD_VALUE;
2076        }
2077        rate = (OMX_U32)(rateFloat);
2078    }
2079    OMX_PARAM_U32TYPE config;
2080    InitOMXParams(&config);
2081    config.nU32 = rate;
2082    status_t err = mOMX->setConfig(
2083            mNode, (OMX_INDEXTYPE)OMX_IndexConfigOperatingRate,
2084            &config, sizeof(config));
2085    if (err != OK) {
2086        ALOGI("codec does not support config operating rate (err %d)", err);
2087    }
2088    return OK;
2089}
2090
2091status_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
2092    OMX_PARAM_PORTDEFINITIONTYPE def;
2093    InitOMXParams(&def);
2094    def.nPortIndex = portIndex;
2095
2096    status_t err = mOMX->getParameter(
2097            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2098
2099    if (err != OK) {
2100        return err;
2101    }
2102
2103    if (def.nBufferSize >= size) {
2104        return OK;
2105    }
2106
2107    def.nBufferSize = size;
2108
2109    err = mOMX->setParameter(
2110            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2111
2112    if (err != OK) {
2113        return err;
2114    }
2115
2116    err = mOMX->getParameter(
2117            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2118
2119    if (err != OK) {
2120        return err;
2121    }
2122
2123    if (def.nBufferSize < size) {
2124        ALOGE("failed to set min buffer size to %zu (is still %u)", size, def.nBufferSize);
2125        return FAILED_TRANSACTION;
2126    }
2127
2128    return OK;
2129}
2130
2131status_t ACodec::selectAudioPortFormat(
2132        OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
2133    OMX_AUDIO_PARAM_PORTFORMATTYPE format;
2134    InitOMXParams(&format);
2135
2136    format.nPortIndex = portIndex;
2137    for (OMX_U32 index = 0;; ++index) {
2138        format.nIndex = index;
2139
2140        status_t err = mOMX->getParameter(
2141                mNode, OMX_IndexParamAudioPortFormat,
2142                &format, sizeof(format));
2143
2144        if (err != OK) {
2145            return err;
2146        }
2147
2148        if (format.eEncoding == desiredFormat) {
2149            break;
2150        }
2151    }
2152
2153    return mOMX->setParameter(
2154            mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format));
2155}
2156
2157status_t ACodec::setupAACCodec(
2158        bool encoder, int32_t numChannels, int32_t sampleRate,
2159        int32_t bitRate, int32_t aacProfile, bool isADTS, int32_t sbrMode,
2160        int32_t maxOutputChannelCount, const drcParams_t& drc,
2161        int32_t pcmLimiterEnable) {
2162    if (encoder && isADTS) {
2163        return -EINVAL;
2164    }
2165
2166    status_t err = setupRawAudioFormat(
2167            encoder ? kPortIndexInput : kPortIndexOutput,
2168            sampleRate,
2169            numChannels);
2170
2171    if (err != OK) {
2172        return err;
2173    }
2174
2175    if (encoder) {
2176        err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
2177
2178        if (err != OK) {
2179            return err;
2180        }
2181
2182        OMX_PARAM_PORTDEFINITIONTYPE def;
2183        InitOMXParams(&def);
2184        def.nPortIndex = kPortIndexOutput;
2185
2186        err = mOMX->getParameter(
2187                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2188
2189        if (err != OK) {
2190            return err;
2191        }
2192
2193        def.format.audio.bFlagErrorConcealment = OMX_TRUE;
2194        def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
2195
2196        err = mOMX->setParameter(
2197                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2198
2199        if (err != OK) {
2200            return err;
2201        }
2202
2203        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
2204        InitOMXParams(&profile);
2205        profile.nPortIndex = kPortIndexOutput;
2206
2207        err = mOMX->getParameter(
2208                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
2209
2210        if (err != OK) {
2211            return err;
2212        }
2213
2214        profile.nChannels = numChannels;
2215
2216        profile.eChannelMode =
2217            (numChannels == 1)
2218                ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
2219
2220        profile.nSampleRate = sampleRate;
2221        profile.nBitRate = bitRate;
2222        profile.nAudioBandWidth = 0;
2223        profile.nFrameLength = 0;
2224        profile.nAACtools = OMX_AUDIO_AACToolAll;
2225        profile.nAACERtools = OMX_AUDIO_AACERNone;
2226        profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
2227        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
2228        switch (sbrMode) {
2229        case 0:
2230            // disable sbr
2231            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
2232            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
2233            break;
2234        case 1:
2235            // enable single-rate sbr
2236            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
2237            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
2238            break;
2239        case 2:
2240            // enable dual-rate sbr
2241            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
2242            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
2243            break;
2244        case -1:
2245            // enable both modes -> the codec will decide which mode should be used
2246            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
2247            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
2248            break;
2249        default:
2250            // unsupported sbr mode
2251            return BAD_VALUE;
2252        }
2253
2254
2255        err = mOMX->setParameter(
2256                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
2257
2258        if (err != OK) {
2259            return err;
2260        }
2261
2262        return err;
2263    }
2264
2265    OMX_AUDIO_PARAM_AACPROFILETYPE profile;
2266    InitOMXParams(&profile);
2267    profile.nPortIndex = kPortIndexInput;
2268
2269    err = mOMX->getParameter(
2270            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
2271
2272    if (err != OK) {
2273        return err;
2274    }
2275
2276    profile.nChannels = numChannels;
2277    profile.nSampleRate = sampleRate;
2278
2279    profile.eAACStreamFormat =
2280        isADTS
2281            ? OMX_AUDIO_AACStreamFormatMP4ADTS
2282            : OMX_AUDIO_AACStreamFormatMP4FF;
2283
2284    OMX_AUDIO_PARAM_ANDROID_AACPRESENTATIONTYPE presentation;
2285    presentation.nMaxOutputChannels = maxOutputChannelCount;
2286    presentation.nDrcCut = drc.drcCut;
2287    presentation.nDrcBoost = drc.drcBoost;
2288    presentation.nHeavyCompression = drc.heavyCompression;
2289    presentation.nTargetReferenceLevel = drc.targetRefLevel;
2290    presentation.nEncodedTargetLevel = drc.encodedTargetLevel;
2291    presentation.nPCMLimiterEnable = pcmLimiterEnable;
2292
2293    status_t res = mOMX->setParameter(mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
2294    if (res == OK) {
2295        // optional parameters, will not cause configuration failure
2296        mOMX->setParameter(mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAacPresentation,
2297                &presentation, sizeof(presentation));
2298    } else {
2299        ALOGW("did not set AudioAndroidAacPresentation due to error %d when setting AudioAac", res);
2300    }
2301    return res;
2302}
2303
2304status_t ACodec::setupAC3Codec(
2305        bool encoder, int32_t numChannels, int32_t sampleRate) {
2306    status_t err = setupRawAudioFormat(
2307            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
2308
2309    if (err != OK) {
2310        return err;
2311    }
2312
2313    if (encoder) {
2314        ALOGW("AC3 encoding is not supported.");
2315        return INVALID_OPERATION;
2316    }
2317
2318    OMX_AUDIO_PARAM_ANDROID_AC3TYPE def;
2319    InitOMXParams(&def);
2320    def.nPortIndex = kPortIndexInput;
2321
2322    err = mOMX->getParameter(
2323            mNode,
2324            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
2325            &def,
2326            sizeof(def));
2327
2328    if (err != OK) {
2329        return err;
2330    }
2331
2332    def.nChannels = numChannels;
2333    def.nSampleRate = sampleRate;
2334
2335    return mOMX->setParameter(
2336            mNode,
2337            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
2338            &def,
2339            sizeof(def));
2340}
2341
2342status_t ACodec::setupEAC3Codec(
2343        bool encoder, int32_t numChannels, int32_t sampleRate) {
2344    status_t err = setupRawAudioFormat(
2345            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
2346
2347    if (err != OK) {
2348        return err;
2349    }
2350
2351    if (encoder) {
2352        ALOGW("EAC3 encoding is not supported.");
2353        return INVALID_OPERATION;
2354    }
2355
2356    OMX_AUDIO_PARAM_ANDROID_EAC3TYPE def;
2357    InitOMXParams(&def);
2358    def.nPortIndex = kPortIndexInput;
2359
2360    err = mOMX->getParameter(
2361            mNode,
2362            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
2363            &def,
2364            sizeof(def));
2365
2366    if (err != OK) {
2367        return err;
2368    }
2369
2370    def.nChannels = numChannels;
2371    def.nSampleRate = sampleRate;
2372
2373    return mOMX->setParameter(
2374            mNode,
2375            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
2376            &def,
2377            sizeof(def));
2378}
2379
2380static OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
2381        bool isAMRWB, int32_t bps) {
2382    if (isAMRWB) {
2383        if (bps <= 6600) {
2384            return OMX_AUDIO_AMRBandModeWB0;
2385        } else if (bps <= 8850) {
2386            return OMX_AUDIO_AMRBandModeWB1;
2387        } else if (bps <= 12650) {
2388            return OMX_AUDIO_AMRBandModeWB2;
2389        } else if (bps <= 14250) {
2390            return OMX_AUDIO_AMRBandModeWB3;
2391        } else if (bps <= 15850) {
2392            return OMX_AUDIO_AMRBandModeWB4;
2393        } else if (bps <= 18250) {
2394            return OMX_AUDIO_AMRBandModeWB5;
2395        } else if (bps <= 19850) {
2396            return OMX_AUDIO_AMRBandModeWB6;
2397        } else if (bps <= 23050) {
2398            return OMX_AUDIO_AMRBandModeWB7;
2399        }
2400
2401        // 23850 bps
2402        return OMX_AUDIO_AMRBandModeWB8;
2403    } else {  // AMRNB
2404        if (bps <= 4750) {
2405            return OMX_AUDIO_AMRBandModeNB0;
2406        } else if (bps <= 5150) {
2407            return OMX_AUDIO_AMRBandModeNB1;
2408        } else if (bps <= 5900) {
2409            return OMX_AUDIO_AMRBandModeNB2;
2410        } else if (bps <= 6700) {
2411            return OMX_AUDIO_AMRBandModeNB3;
2412        } else if (bps <= 7400) {
2413            return OMX_AUDIO_AMRBandModeNB4;
2414        } else if (bps <= 7950) {
2415            return OMX_AUDIO_AMRBandModeNB5;
2416        } else if (bps <= 10200) {
2417            return OMX_AUDIO_AMRBandModeNB6;
2418        }
2419
2420        // 12200 bps
2421        return OMX_AUDIO_AMRBandModeNB7;
2422    }
2423}
2424
2425status_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
2426    OMX_AUDIO_PARAM_AMRTYPE def;
2427    InitOMXParams(&def);
2428    def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
2429
2430    status_t err =
2431        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
2432
2433    if (err != OK) {
2434        return err;
2435    }
2436
2437    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
2438    def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
2439
2440    err = mOMX->setParameter(
2441            mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
2442
2443    if (err != OK) {
2444        return err;
2445    }
2446
2447    return setupRawAudioFormat(
2448            encoder ? kPortIndexInput : kPortIndexOutput,
2449            isWAMR ? 16000 : 8000 /* sampleRate */,
2450            1 /* numChannels */);
2451}
2452
2453status_t ACodec::setupG711Codec(bool encoder, int32_t sampleRate, int32_t numChannels) {
2454    if (encoder) {
2455        return INVALID_OPERATION;
2456    }
2457
2458    return setupRawAudioFormat(
2459            kPortIndexInput, sampleRate, numChannels);
2460}
2461
2462status_t ACodec::setupFlacCodec(
2463        bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
2464
2465    if (encoder) {
2466        OMX_AUDIO_PARAM_FLACTYPE def;
2467        InitOMXParams(&def);
2468        def.nPortIndex = kPortIndexOutput;
2469
2470        // configure compression level
2471        status_t err = mOMX->getParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
2472        if (err != OK) {
2473            ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
2474            return err;
2475        }
2476        def.nCompressionLevel = compressionLevel;
2477        err = mOMX->setParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
2478        if (err != OK) {
2479            ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
2480            return err;
2481        }
2482    }
2483
2484    return setupRawAudioFormat(
2485            encoder ? kPortIndexInput : kPortIndexOutput,
2486            sampleRate,
2487            numChannels);
2488}
2489
2490status_t ACodec::setupRawAudioFormat(
2491        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
2492    OMX_PARAM_PORTDEFINITIONTYPE def;
2493    InitOMXParams(&def);
2494    def.nPortIndex = portIndex;
2495
2496    status_t err = mOMX->getParameter(
2497            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2498
2499    if (err != OK) {
2500        return err;
2501    }
2502
2503    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
2504
2505    err = mOMX->setParameter(
2506            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2507
2508    if (err != OK) {
2509        return err;
2510    }
2511
2512    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
2513    InitOMXParams(&pcmParams);
2514    pcmParams.nPortIndex = portIndex;
2515
2516    err = mOMX->getParameter(
2517            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
2518
2519    if (err != OK) {
2520        return err;
2521    }
2522
2523    pcmParams.nChannels = numChannels;
2524    pcmParams.eNumData = OMX_NumericalDataSigned;
2525    pcmParams.bInterleaved = OMX_TRUE;
2526    pcmParams.nBitPerSample = 16;
2527    pcmParams.nSamplingRate = sampleRate;
2528    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
2529
2530    if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
2531        return OMX_ErrorNone;
2532    }
2533
2534    return mOMX->setParameter(
2535            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
2536}
2537
2538status_t ACodec::configureTunneledVideoPlayback(
2539        int32_t audioHwSync, const sp<ANativeWindow> &nativeWindow) {
2540    native_handle_t* sidebandHandle;
2541
2542    status_t err = mOMX->configureVideoTunnelMode(
2543            mNode, kPortIndexOutput, OMX_TRUE, audioHwSync, &sidebandHandle);
2544    if (err != OK) {
2545        ALOGE("configureVideoTunnelMode failed! (err %d).", err);
2546        return err;
2547    }
2548
2549    err = native_window_set_sideband_stream(nativeWindow.get(), sidebandHandle);
2550    if (err != OK) {
2551        ALOGE("native_window_set_sideband_stream(%p) failed! (err %d).",
2552                sidebandHandle, err);
2553        return err;
2554    }
2555
2556    return OK;
2557}
2558
2559status_t ACodec::setVideoPortFormatType(
2560        OMX_U32 portIndex,
2561        OMX_VIDEO_CODINGTYPE compressionFormat,
2562        OMX_COLOR_FORMATTYPE colorFormat,
2563        bool usingNativeBuffers) {
2564    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
2565    InitOMXParams(&format);
2566    format.nPortIndex = portIndex;
2567    format.nIndex = 0;
2568    bool found = false;
2569
2570    OMX_U32 index = 0;
2571    for (;;) {
2572        format.nIndex = index;
2573        status_t err = mOMX->getParameter(
2574                mNode, OMX_IndexParamVideoPortFormat,
2575                &format, sizeof(format));
2576
2577        if (err != OK) {
2578            return err;
2579        }
2580
2581        // substitute back flexible color format to codec supported format
2582        OMX_U32 flexibleEquivalent;
2583        if (compressionFormat == OMX_VIDEO_CodingUnused
2584                && isFlexibleColorFormat(
2585                        mOMX, mNode, format.eColorFormat, usingNativeBuffers, &flexibleEquivalent)
2586                && colorFormat == flexibleEquivalent) {
2587            ALOGI("[%s] using color format %#x in place of %#x",
2588                    mComponentName.c_str(), format.eColorFormat, colorFormat);
2589            colorFormat = format.eColorFormat;
2590        }
2591
2592        // The following assertion is violated by TI's video decoder.
2593        // CHECK_EQ(format.nIndex, index);
2594
2595        if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
2596            if (portIndex == kPortIndexInput
2597                    && colorFormat == format.eColorFormat) {
2598                // eCompressionFormat does not seem right.
2599                found = true;
2600                break;
2601            }
2602            if (portIndex == kPortIndexOutput
2603                    && compressionFormat == format.eCompressionFormat) {
2604                // eColorFormat does not seem right.
2605                found = true;
2606                break;
2607            }
2608        }
2609
2610        if (format.eCompressionFormat == compressionFormat
2611            && format.eColorFormat == colorFormat) {
2612            found = true;
2613            break;
2614        }
2615
2616        ++index;
2617    }
2618
2619    if (!found) {
2620        return UNKNOWN_ERROR;
2621    }
2622
2623    status_t err = mOMX->setParameter(
2624            mNode, OMX_IndexParamVideoPortFormat,
2625            &format, sizeof(format));
2626
2627    return err;
2628}
2629
2630// Set optimal output format. OMX component lists output formats in the order
2631// of preference, but this got more complicated since the introduction of flexible
2632// YUV formats. We support a legacy behavior for applications that do not use
2633// surface output, do not specify an output format, but expect a "usable" standard
2634// OMX format. SW readable and standard formats must be flex-YUV.
2635//
2636// Suggested preference order:
2637// - optimal format for texture rendering (mediaplayer behavior)
2638// - optimal SW readable & texture renderable format (flex-YUV support)
2639// - optimal SW readable non-renderable format (flex-YUV bytebuffer support)
2640// - legacy "usable" standard formats
2641//
2642// For legacy support, we prefer a standard format, but will settle for a SW readable
2643// flex-YUV format.
2644status_t ACodec::setSupportedOutputFormat(bool getLegacyFlexibleFormat) {
2645    OMX_VIDEO_PARAM_PORTFORMATTYPE format, legacyFormat;
2646    InitOMXParams(&format);
2647    format.nPortIndex = kPortIndexOutput;
2648
2649    InitOMXParams(&legacyFormat);
2650    // this field will change when we find a suitable legacy format
2651    legacyFormat.eColorFormat = OMX_COLOR_FormatUnused;
2652
2653    for (OMX_U32 index = 0; ; ++index) {
2654        format.nIndex = index;
2655        status_t err = mOMX->getParameter(
2656                mNode, OMX_IndexParamVideoPortFormat,
2657                &format, sizeof(format));
2658        if (err != OK) {
2659            // no more formats, pick legacy format if found
2660            if (legacyFormat.eColorFormat != OMX_COLOR_FormatUnused) {
2661                 memcpy(&format, &legacyFormat, sizeof(format));
2662                 break;
2663            }
2664            return err;
2665        }
2666        if (format.eCompressionFormat != OMX_VIDEO_CodingUnused) {
2667            return OMX_ErrorBadParameter;
2668        }
2669        if (!getLegacyFlexibleFormat) {
2670            break;
2671        }
2672        // standard formats that were exposed to users before
2673        if (format.eColorFormat == OMX_COLOR_FormatYUV420Planar
2674                || format.eColorFormat == OMX_COLOR_FormatYUV420PackedPlanar
2675                || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar
2676                || format.eColorFormat == OMX_COLOR_FormatYUV420PackedSemiPlanar
2677                || format.eColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar) {
2678            break;
2679        }
2680        // find best legacy non-standard format
2681        OMX_U32 flexibleEquivalent;
2682        if (legacyFormat.eColorFormat == OMX_COLOR_FormatUnused
2683                && isFlexibleColorFormat(
2684                        mOMX, mNode, format.eColorFormat, false /* usingNativeBuffers */,
2685                        &flexibleEquivalent)
2686                && flexibleEquivalent == OMX_COLOR_FormatYUV420Flexible) {
2687            memcpy(&legacyFormat, &format, sizeof(format));
2688        }
2689    }
2690    return mOMX->setParameter(
2691            mNode, OMX_IndexParamVideoPortFormat,
2692            &format, sizeof(format));
2693}
2694
2695static const struct VideoCodingMapEntry {
2696    const char *mMime;
2697    OMX_VIDEO_CODINGTYPE mVideoCodingType;
2698} kVideoCodingMapEntry[] = {
2699    { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC },
2700    { MEDIA_MIMETYPE_VIDEO_HEVC, OMX_VIDEO_CodingHEVC },
2701    { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 },
2702    { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 },
2703    { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 },
2704    { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 },
2705    { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 },
2706};
2707
2708static status_t GetVideoCodingTypeFromMime(
2709        const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
2710    for (size_t i = 0;
2711         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
2712         ++i) {
2713        if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) {
2714            *codingType = kVideoCodingMapEntry[i].mVideoCodingType;
2715            return OK;
2716        }
2717    }
2718
2719    *codingType = OMX_VIDEO_CodingUnused;
2720
2721    return ERROR_UNSUPPORTED;
2722}
2723
2724static status_t GetMimeTypeForVideoCoding(
2725        OMX_VIDEO_CODINGTYPE codingType, AString *mime) {
2726    for (size_t i = 0;
2727         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
2728         ++i) {
2729        if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) {
2730            *mime = kVideoCodingMapEntry[i].mMime;
2731            return OK;
2732        }
2733    }
2734
2735    mime->clear();
2736
2737    return ERROR_UNSUPPORTED;
2738}
2739
2740status_t ACodec::setupVideoDecoder(
2741        const char *mime, const sp<AMessage> &msg, bool haveNativeWindow) {
2742    int32_t width, height;
2743    if (!msg->findInt32("width", &width)
2744            || !msg->findInt32("height", &height)) {
2745        return INVALID_OPERATION;
2746    }
2747
2748    OMX_VIDEO_CODINGTYPE compressionFormat;
2749    status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
2750
2751    if (err != OK) {
2752        return err;
2753    }
2754
2755    err = setVideoPortFormatType(
2756            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
2757
2758    if (err != OK) {
2759        return err;
2760    }
2761
2762    int32_t tmp;
2763    if (msg->findInt32("color-format", &tmp)) {
2764        OMX_COLOR_FORMATTYPE colorFormat =
2765            static_cast<OMX_COLOR_FORMATTYPE>(tmp);
2766        err = setVideoPortFormatType(
2767                kPortIndexOutput, OMX_VIDEO_CodingUnused, colorFormat, haveNativeWindow);
2768        if (err != OK) {
2769            ALOGW("[%s] does not support color format %d",
2770                  mComponentName.c_str(), colorFormat);
2771            err = setSupportedOutputFormat(!haveNativeWindow /* getLegacyFlexibleFormat */);
2772        }
2773    } else {
2774        err = setSupportedOutputFormat(!haveNativeWindow /* getLegacyFlexibleFormat */);
2775    }
2776
2777    if (err != OK) {
2778        return err;
2779    }
2780
2781    int32_t frameRateInt;
2782    float frameRateFloat;
2783    if (!msg->findFloat("frame-rate", &frameRateFloat)) {
2784        if (!msg->findInt32("frame-rate", &frameRateInt)) {
2785            frameRateInt = -1;
2786        }
2787        frameRateFloat = (float)frameRateInt;
2788    }
2789
2790    err = setVideoFormatOnPort(
2791            kPortIndexInput, width, height, compressionFormat, frameRateFloat);
2792
2793    if (err != OK) {
2794        return err;
2795    }
2796
2797    err = setVideoFormatOnPort(
2798            kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
2799
2800    if (err != OK) {
2801        return err;
2802    }
2803
2804    return OK;
2805}
2806
2807status_t ACodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) {
2808    int32_t tmp;
2809    if (!msg->findInt32("color-format", &tmp)) {
2810        return INVALID_OPERATION;
2811    }
2812
2813    OMX_COLOR_FORMATTYPE colorFormat =
2814        static_cast<OMX_COLOR_FORMATTYPE>(tmp);
2815
2816    status_t err = setVideoPortFormatType(
2817            kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
2818
2819    if (err != OK) {
2820        ALOGE("[%s] does not support color format %d",
2821              mComponentName.c_str(), colorFormat);
2822
2823        return err;
2824    }
2825
2826    /* Input port configuration */
2827
2828    OMX_PARAM_PORTDEFINITIONTYPE def;
2829    InitOMXParams(&def);
2830
2831    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
2832
2833    def.nPortIndex = kPortIndexInput;
2834
2835    err = mOMX->getParameter(
2836            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2837
2838    if (err != OK) {
2839        return err;
2840    }
2841
2842    int32_t width, height, bitrate;
2843    if (!msg->findInt32("width", &width)
2844            || !msg->findInt32("height", &height)
2845            || !msg->findInt32("bitrate", &bitrate)) {
2846        return INVALID_OPERATION;
2847    }
2848
2849    video_def->nFrameWidth = width;
2850    video_def->nFrameHeight = height;
2851
2852    int32_t stride;
2853    if (!msg->findInt32("stride", &stride)) {
2854        stride = width;
2855    }
2856
2857    video_def->nStride = stride;
2858
2859    int32_t sliceHeight;
2860    if (!msg->findInt32("slice-height", &sliceHeight)) {
2861        sliceHeight = height;
2862    }
2863
2864    video_def->nSliceHeight = sliceHeight;
2865
2866    def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
2867
2868    float frameRate;
2869    if (!msg->findFloat("frame-rate", &frameRate)) {
2870        int32_t tmp;
2871        if (!msg->findInt32("frame-rate", &tmp)) {
2872            return INVALID_OPERATION;
2873        }
2874        frameRate = (float)tmp;
2875        mTimePerFrameUs = (int64_t) (1000000.0f / frameRate);
2876    }
2877
2878    video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
2879    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
2880    // this is redundant as it was already set up in setVideoPortFormatType
2881    // FIXME for now skip this only for flexible YUV formats
2882    if (colorFormat != OMX_COLOR_FormatYUV420Flexible) {
2883        video_def->eColorFormat = colorFormat;
2884    }
2885
2886    err = mOMX->setParameter(
2887            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2888
2889    if (err != OK) {
2890        ALOGE("[%s] failed to set input port definition parameters.",
2891              mComponentName.c_str());
2892
2893        return err;
2894    }
2895
2896    /* Output port configuration */
2897
2898    OMX_VIDEO_CODINGTYPE compressionFormat;
2899    err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
2900
2901    if (err != OK) {
2902        return err;
2903    }
2904
2905    err = setVideoPortFormatType(
2906            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
2907
2908    if (err != OK) {
2909        ALOGE("[%s] does not support compression format %d",
2910             mComponentName.c_str(), compressionFormat);
2911
2912        return err;
2913    }
2914
2915    def.nPortIndex = kPortIndexOutput;
2916
2917    err = mOMX->getParameter(
2918            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2919
2920    if (err != OK) {
2921        return err;
2922    }
2923
2924    video_def->nFrameWidth = width;
2925    video_def->nFrameHeight = height;
2926    video_def->xFramerate = 0;
2927    video_def->nBitrate = bitrate;
2928    video_def->eCompressionFormat = compressionFormat;
2929    video_def->eColorFormat = OMX_COLOR_FormatUnused;
2930
2931    err = mOMX->setParameter(
2932            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2933
2934    if (err != OK) {
2935        ALOGE("[%s] failed to set output port definition parameters.",
2936              mComponentName.c_str());
2937
2938        return err;
2939    }
2940
2941    switch (compressionFormat) {
2942        case OMX_VIDEO_CodingMPEG4:
2943            err = setupMPEG4EncoderParameters(msg);
2944            break;
2945
2946        case OMX_VIDEO_CodingH263:
2947            err = setupH263EncoderParameters(msg);
2948            break;
2949
2950        case OMX_VIDEO_CodingAVC:
2951            err = setupAVCEncoderParameters(msg);
2952            break;
2953
2954        case OMX_VIDEO_CodingHEVC:
2955            err = setupHEVCEncoderParameters(msg);
2956            break;
2957
2958        case OMX_VIDEO_CodingVP8:
2959        case OMX_VIDEO_CodingVP9:
2960            err = setupVPXEncoderParameters(msg);
2961            break;
2962
2963        default:
2964            break;
2965    }
2966
2967    if (err == OK) {
2968        ALOGI("setupVideoEncoder succeeded");
2969    }
2970
2971    return err;
2972}
2973
2974status_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) {
2975    OMX_VIDEO_PARAM_INTRAREFRESHTYPE params;
2976    InitOMXParams(&params);
2977    params.nPortIndex = kPortIndexOutput;
2978
2979    params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode);
2980
2981    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic ||
2982            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
2983        int32_t mbs;
2984        if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) {
2985            return INVALID_OPERATION;
2986        }
2987        params.nCirMBs = mbs;
2988    }
2989
2990    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive ||
2991            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
2992        int32_t mbs;
2993        if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) {
2994            return INVALID_OPERATION;
2995        }
2996        params.nAirMBs = mbs;
2997
2998        int32_t ref;
2999        if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) {
3000            return INVALID_OPERATION;
3001        }
3002        params.nAirRef = ref;
3003    }
3004
3005    status_t err = mOMX->setParameter(
3006            mNode, OMX_IndexParamVideoIntraRefresh,
3007            &params, sizeof(params));
3008    return err;
3009}
3010
3011static OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
3012    if (iFramesInterval < 0) {
3013        return 0xFFFFFFFF;
3014    } else if (iFramesInterval == 0) {
3015        return 0;
3016    }
3017    OMX_U32 ret = frameRate * iFramesInterval;
3018    return ret;
3019}
3020
3021static OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) {
3022    int32_t tmp;
3023    if (!msg->findInt32("bitrate-mode", &tmp)) {
3024        return OMX_Video_ControlRateVariable;
3025    }
3026
3027    return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp);
3028}
3029
3030status_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
3031    int32_t bitrate, iFrameInterval;
3032    if (!msg->findInt32("bitrate", &bitrate)
3033            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
3034        return INVALID_OPERATION;
3035    }
3036
3037    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
3038
3039    float frameRate;
3040    if (!msg->findFloat("frame-rate", &frameRate)) {
3041        int32_t tmp;
3042        if (!msg->findInt32("frame-rate", &tmp)) {
3043            return INVALID_OPERATION;
3044        }
3045        frameRate = (float)tmp;
3046    }
3047
3048    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
3049    InitOMXParams(&mpeg4type);
3050    mpeg4type.nPortIndex = kPortIndexOutput;
3051
3052    status_t err = mOMX->getParameter(
3053            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
3054
3055    if (err != OK) {
3056        return err;
3057    }
3058
3059    mpeg4type.nSliceHeaderSpacing = 0;
3060    mpeg4type.bSVH = OMX_FALSE;
3061    mpeg4type.bGov = OMX_FALSE;
3062
3063    mpeg4type.nAllowedPictureTypes =
3064        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
3065
3066    mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
3067    if (mpeg4type.nPFrames == 0) {
3068        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
3069    }
3070    mpeg4type.nBFrames = 0;
3071    mpeg4type.nIDCVLCThreshold = 0;
3072    mpeg4type.bACPred = OMX_TRUE;
3073    mpeg4type.nMaxPacketSize = 256;
3074    mpeg4type.nTimeIncRes = 1000;
3075    mpeg4type.nHeaderExtension = 0;
3076    mpeg4type.bReversibleVLC = OMX_FALSE;
3077
3078    int32_t profile;
3079    if (msg->findInt32("profile", &profile)) {
3080        int32_t level;
3081        if (!msg->findInt32("level", &level)) {
3082            return INVALID_OPERATION;
3083        }
3084
3085        err = verifySupportForProfileAndLevel(profile, level);
3086
3087        if (err != OK) {
3088            return err;
3089        }
3090
3091        mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
3092        mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
3093    }
3094
3095    err = mOMX->setParameter(
3096            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
3097
3098    if (err != OK) {
3099        return err;
3100    }
3101
3102    err = configureBitrate(bitrate, bitrateMode);
3103
3104    if (err != OK) {
3105        return err;
3106    }
3107
3108    return setupErrorCorrectionParameters();
3109}
3110
3111status_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
3112    int32_t bitrate, iFrameInterval;
3113    if (!msg->findInt32("bitrate", &bitrate)
3114            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
3115        return INVALID_OPERATION;
3116    }
3117
3118    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
3119
3120    float frameRate;
3121    if (!msg->findFloat("frame-rate", &frameRate)) {
3122        int32_t tmp;
3123        if (!msg->findInt32("frame-rate", &tmp)) {
3124            return INVALID_OPERATION;
3125        }
3126        frameRate = (float)tmp;
3127    }
3128
3129    OMX_VIDEO_PARAM_H263TYPE h263type;
3130    InitOMXParams(&h263type);
3131    h263type.nPortIndex = kPortIndexOutput;
3132
3133    status_t err = mOMX->getParameter(
3134            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
3135
3136    if (err != OK) {
3137        return err;
3138    }
3139
3140    h263type.nAllowedPictureTypes =
3141        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
3142
3143    h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
3144    if (h263type.nPFrames == 0) {
3145        h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
3146    }
3147    h263type.nBFrames = 0;
3148
3149    int32_t profile;
3150    if (msg->findInt32("profile", &profile)) {
3151        int32_t level;
3152        if (!msg->findInt32("level", &level)) {
3153            return INVALID_OPERATION;
3154        }
3155
3156        err = verifySupportForProfileAndLevel(profile, level);
3157
3158        if (err != OK) {
3159            return err;
3160        }
3161
3162        h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
3163        h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
3164    }
3165
3166    h263type.bPLUSPTYPEAllowed = OMX_FALSE;
3167    h263type.bForceRoundingTypeToZero = OMX_FALSE;
3168    h263type.nPictureHeaderRepetition = 0;
3169    h263type.nGOBHeaderInterval = 0;
3170
3171    err = mOMX->setParameter(
3172            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
3173
3174    if (err != OK) {
3175        return err;
3176    }
3177
3178    err = configureBitrate(bitrate, bitrateMode);
3179
3180    if (err != OK) {
3181        return err;
3182    }
3183
3184    return setupErrorCorrectionParameters();
3185}
3186
3187// static
3188int /* OMX_VIDEO_AVCLEVELTYPE */ ACodec::getAVCLevelFor(
3189        int width, int height, int rate, int bitrate,
3190        OMX_VIDEO_AVCPROFILETYPE profile) {
3191    // convert bitrate to main/baseline profile kbps equivalent
3192    switch (profile) {
3193        case OMX_VIDEO_AVCProfileHigh10:
3194            bitrate = divUp(bitrate, 3000); break;
3195        case OMX_VIDEO_AVCProfileHigh:
3196            bitrate = divUp(bitrate, 1250); break;
3197        default:
3198            bitrate = divUp(bitrate, 1000); break;
3199    }
3200
3201    // convert size and rate to MBs
3202    width = divUp(width, 16);
3203    height = divUp(height, 16);
3204    int mbs = width * height;
3205    rate *= mbs;
3206    int maxDimension = max(width, height);
3207
3208    static const int limits[][5] = {
3209        /*   MBps     MB   dim  bitrate        level */
3210        {    1485,    99,  28,     64, OMX_VIDEO_AVCLevel1  },
3211        {    1485,    99,  28,    128, OMX_VIDEO_AVCLevel1b },
3212        {    3000,   396,  56,    192, OMX_VIDEO_AVCLevel11 },
3213        {    6000,   396,  56,    384, OMX_VIDEO_AVCLevel12 },
3214        {   11880,   396,  56,    768, OMX_VIDEO_AVCLevel13 },
3215        {   11880,   396,  56,   2000, OMX_VIDEO_AVCLevel2  },
3216        {   19800,   792,  79,   4000, OMX_VIDEO_AVCLevel21 },
3217        {   20250,  1620, 113,   4000, OMX_VIDEO_AVCLevel22 },
3218        {   40500,  1620, 113,  10000, OMX_VIDEO_AVCLevel3  },
3219        {  108000,  3600, 169,  14000, OMX_VIDEO_AVCLevel31 },
3220        {  216000,  5120, 202,  20000, OMX_VIDEO_AVCLevel32 },
3221        {  245760,  8192, 256,  20000, OMX_VIDEO_AVCLevel4  },
3222        {  245760,  8192, 256,  50000, OMX_VIDEO_AVCLevel41 },
3223        {  522240,  8704, 263,  50000, OMX_VIDEO_AVCLevel42 },
3224        {  589824, 22080, 420, 135000, OMX_VIDEO_AVCLevel5  },
3225        {  983040, 36864, 543, 240000, OMX_VIDEO_AVCLevel51 },
3226        { 2073600, 36864, 543, 240000, OMX_VIDEO_AVCLevel52 },
3227    };
3228
3229    for (size_t i = 0; i < ARRAY_SIZE(limits); i++) {
3230        const int (&limit)[5] = limits[i];
3231        if (rate <= limit[0] && mbs <= limit[1] && maxDimension <= limit[2]
3232                && bitrate <= limit[3]) {
3233            return limit[4];
3234        }
3235    }
3236    return 0;
3237}
3238
3239status_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
3240    int32_t bitrate, iFrameInterval;
3241    if (!msg->findInt32("bitrate", &bitrate)
3242            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
3243        return INVALID_OPERATION;
3244    }
3245
3246    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
3247
3248    float frameRate;
3249    if (!msg->findFloat("frame-rate", &frameRate)) {
3250        int32_t tmp;
3251        if (!msg->findInt32("frame-rate", &tmp)) {
3252            return INVALID_OPERATION;
3253        }
3254        frameRate = (float)tmp;
3255    }
3256
3257    status_t err = OK;
3258    int32_t intraRefreshMode = 0;
3259    if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) {
3260        err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode);
3261        if (err != OK) {
3262            ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
3263                    err, intraRefreshMode);
3264            return err;
3265        }
3266    }
3267
3268    OMX_VIDEO_PARAM_AVCTYPE h264type;
3269    InitOMXParams(&h264type);
3270    h264type.nPortIndex = kPortIndexOutput;
3271
3272    err = mOMX->getParameter(
3273            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
3274
3275    if (err != OK) {
3276        return err;
3277    }
3278
3279    h264type.nAllowedPictureTypes =
3280        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
3281
3282    int32_t profile;
3283    if (msg->findInt32("profile", &profile)) {
3284        int32_t level;
3285        if (!msg->findInt32("level", &level)) {
3286            return INVALID_OPERATION;
3287        }
3288
3289        err = verifySupportForProfileAndLevel(profile, level);
3290
3291        if (err != OK) {
3292            return err;
3293        }
3294
3295        h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
3296        h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
3297    }
3298
3299    // XXX
3300    if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) {
3301        ALOGW("Use baseline profile instead of %d for AVC recording",
3302            h264type.eProfile);
3303        h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
3304    }
3305
3306    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
3307        h264type.nSliceHeaderSpacing = 0;
3308        h264type.bUseHadamard = OMX_TRUE;
3309        h264type.nRefFrames = 1;
3310        h264type.nBFrames = 0;
3311        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
3312        if (h264type.nPFrames == 0) {
3313            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
3314        }
3315        h264type.nRefIdx10ActiveMinus1 = 0;
3316        h264type.nRefIdx11ActiveMinus1 = 0;
3317        h264type.bEntropyCodingCABAC = OMX_FALSE;
3318        h264type.bWeightedPPrediction = OMX_FALSE;
3319        h264type.bconstIpred = OMX_FALSE;
3320        h264type.bDirect8x8Inference = OMX_FALSE;
3321        h264type.bDirectSpatialTemporal = OMX_FALSE;
3322        h264type.nCabacInitIdc = 0;
3323    }
3324
3325    if (h264type.nBFrames != 0) {
3326        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
3327    }
3328
3329    h264type.bEnableUEP = OMX_FALSE;
3330    h264type.bEnableFMO = OMX_FALSE;
3331    h264type.bEnableASO = OMX_FALSE;
3332    h264type.bEnableRS = OMX_FALSE;
3333    h264type.bFrameMBsOnly = OMX_TRUE;
3334    h264type.bMBAFF = OMX_FALSE;
3335    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
3336
3337    err = mOMX->setParameter(
3338            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
3339
3340    if (err != OK) {
3341        return err;
3342    }
3343
3344    return configureBitrate(bitrate, bitrateMode);
3345}
3346
3347status_t ACodec::setupHEVCEncoderParameters(const sp<AMessage> &msg) {
3348    int32_t bitrate, iFrameInterval;
3349    if (!msg->findInt32("bitrate", &bitrate)
3350            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
3351        return INVALID_OPERATION;
3352    }
3353
3354    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
3355
3356    float frameRate;
3357    if (!msg->findFloat("frame-rate", &frameRate)) {
3358        int32_t tmp;
3359        if (!msg->findInt32("frame-rate", &tmp)) {
3360            return INVALID_OPERATION;
3361        }
3362        frameRate = (float)tmp;
3363    }
3364
3365    OMX_VIDEO_PARAM_HEVCTYPE hevcType;
3366    InitOMXParams(&hevcType);
3367    hevcType.nPortIndex = kPortIndexOutput;
3368
3369    status_t err = OK;
3370    err = mOMX->getParameter(
3371            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
3372    if (err != OK) {
3373        return err;
3374    }
3375
3376    int32_t profile;
3377    if (msg->findInt32("profile", &profile)) {
3378        int32_t level;
3379        if (!msg->findInt32("level", &level)) {
3380            return INVALID_OPERATION;
3381        }
3382
3383        err = verifySupportForProfileAndLevel(profile, level);
3384        if (err != OK) {
3385            return err;
3386        }
3387
3388        hevcType.eProfile = static_cast<OMX_VIDEO_HEVCPROFILETYPE>(profile);
3389        hevcType.eLevel = static_cast<OMX_VIDEO_HEVCLEVELTYPE>(level);
3390    }
3391
3392    // TODO: Need OMX structure definition for setting iFrameInterval
3393
3394    err = mOMX->setParameter(
3395            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
3396    if (err != OK) {
3397        return err;
3398    }
3399
3400    return configureBitrate(bitrate, bitrateMode);
3401}
3402
3403status_t ACodec::setupVPXEncoderParameters(const sp<AMessage> &msg) {
3404    int32_t bitrate;
3405    int32_t iFrameInterval = 0;
3406    size_t tsLayers = 0;
3407    OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE pattern =
3408        OMX_VIDEO_VPXTemporalLayerPatternNone;
3409    static const uint32_t kVp8LayerRateAlloction
3410        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS]
3411        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS] = {
3412        {100, 100, 100},  // 1 layer
3413        { 60, 100, 100},  // 2 layers {60%, 40%}
3414        { 40,  60, 100},  // 3 layers {40%, 20%, 40%}
3415    };
3416    if (!msg->findInt32("bitrate", &bitrate)) {
3417        return INVALID_OPERATION;
3418    }
3419    msg->findInt32("i-frame-interval", &iFrameInterval);
3420
3421    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
3422
3423    float frameRate;
3424    if (!msg->findFloat("frame-rate", &frameRate)) {
3425        int32_t tmp;
3426        if (!msg->findInt32("frame-rate", &tmp)) {
3427            return INVALID_OPERATION;
3428        }
3429        frameRate = (float)tmp;
3430    }
3431
3432    AString tsSchema;
3433    if (msg->findString("ts-schema", &tsSchema)) {
3434        if (tsSchema == "webrtc.vp8.1-layer") {
3435            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
3436            tsLayers = 1;
3437        } else if (tsSchema == "webrtc.vp8.2-layer") {
3438            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
3439            tsLayers = 2;
3440        } else if (tsSchema == "webrtc.vp8.3-layer") {
3441            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
3442            tsLayers = 3;
3443        } else {
3444            ALOGW("Unsupported ts-schema [%s]", tsSchema.c_str());
3445        }
3446    }
3447
3448    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
3449    InitOMXParams(&vp8type);
3450    vp8type.nPortIndex = kPortIndexOutput;
3451    status_t err = mOMX->getParameter(
3452            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
3453            &vp8type, sizeof(vp8type));
3454
3455    if (err == OK) {
3456        if (iFrameInterval > 0) {
3457            vp8type.nKeyFrameInterval = setPFramesSpacing(iFrameInterval, frameRate);
3458        }
3459        vp8type.eTemporalPattern = pattern;
3460        vp8type.nTemporalLayerCount = tsLayers;
3461        if (tsLayers > 0) {
3462            for (size_t i = 0; i < OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS; i++) {
3463                vp8type.nTemporalLayerBitrateRatio[i] =
3464                    kVp8LayerRateAlloction[tsLayers - 1][i];
3465            }
3466        }
3467        if (bitrateMode == OMX_Video_ControlRateConstant) {
3468            vp8type.nMinQuantizer = 2;
3469            vp8type.nMaxQuantizer = 63;
3470        }
3471
3472        err = mOMX->setParameter(
3473                mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
3474                &vp8type, sizeof(vp8type));
3475        if (err != OK) {
3476            ALOGW("Extended VP8 parameters set failed: %d", err);
3477        }
3478    }
3479
3480    return configureBitrate(bitrate, bitrateMode);
3481}
3482
3483status_t ACodec::verifySupportForProfileAndLevel(
3484        int32_t profile, int32_t level) {
3485    OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
3486    InitOMXParams(&params);
3487    params.nPortIndex = kPortIndexOutput;
3488
3489    for (params.nProfileIndex = 0;; ++params.nProfileIndex) {
3490        status_t err = mOMX->getParameter(
3491                mNode,
3492                OMX_IndexParamVideoProfileLevelQuerySupported,
3493                &params,
3494                sizeof(params));
3495
3496        if (err != OK) {
3497            return err;
3498        }
3499
3500        int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
3501        int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
3502
3503        if (profile == supportedProfile && level <= supportedLevel) {
3504            return OK;
3505        }
3506    }
3507}
3508
3509status_t ACodec::configureBitrate(
3510        int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) {
3511    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
3512    InitOMXParams(&bitrateType);
3513    bitrateType.nPortIndex = kPortIndexOutput;
3514
3515    status_t err = mOMX->getParameter(
3516            mNode, OMX_IndexParamVideoBitrate,
3517            &bitrateType, sizeof(bitrateType));
3518
3519    if (err != OK) {
3520        return err;
3521    }
3522
3523    bitrateType.eControlRate = bitrateMode;
3524    bitrateType.nTargetBitrate = bitrate;
3525
3526    return mOMX->setParameter(
3527            mNode, OMX_IndexParamVideoBitrate,
3528            &bitrateType, sizeof(bitrateType));
3529}
3530
3531status_t ACodec::setupErrorCorrectionParameters() {
3532    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
3533    InitOMXParams(&errorCorrectionType);
3534    errorCorrectionType.nPortIndex = kPortIndexOutput;
3535
3536    status_t err = mOMX->getParameter(
3537            mNode, OMX_IndexParamVideoErrorCorrection,
3538            &errorCorrectionType, sizeof(errorCorrectionType));
3539
3540    if (err != OK) {
3541        return OK;  // Optional feature. Ignore this failure
3542    }
3543
3544    errorCorrectionType.bEnableHEC = OMX_FALSE;
3545    errorCorrectionType.bEnableResync = OMX_TRUE;
3546    errorCorrectionType.nResynchMarkerSpacing = 256;
3547    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
3548    errorCorrectionType.bEnableRVLC = OMX_FALSE;
3549
3550    return mOMX->setParameter(
3551            mNode, OMX_IndexParamVideoErrorCorrection,
3552            &errorCorrectionType, sizeof(errorCorrectionType));
3553}
3554
3555status_t ACodec::setVideoFormatOnPort(
3556        OMX_U32 portIndex,
3557        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat,
3558        float frameRate) {
3559    OMX_PARAM_PORTDEFINITIONTYPE def;
3560    InitOMXParams(&def);
3561    def.nPortIndex = portIndex;
3562
3563    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
3564
3565    status_t err = mOMX->getParameter(
3566            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
3567    if (err != OK) {
3568        return err;
3569    }
3570
3571    if (portIndex == kPortIndexInput) {
3572        // XXX Need a (much) better heuristic to compute input buffer sizes.
3573        const size_t X = 64 * 1024;
3574        if (def.nBufferSize < X) {
3575            def.nBufferSize = X;
3576        }
3577    }
3578
3579    if (def.eDomain != OMX_PortDomainVideo) {
3580        ALOGE("expected video port, got %s(%d)", asString(def.eDomain), def.eDomain);
3581        return FAILED_TRANSACTION;
3582    }
3583
3584    video_def->nFrameWidth = width;
3585    video_def->nFrameHeight = height;
3586
3587    if (portIndex == kPortIndexInput) {
3588        video_def->eCompressionFormat = compressionFormat;
3589        video_def->eColorFormat = OMX_COLOR_FormatUnused;
3590        if (frameRate >= 0) {
3591            video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
3592        }
3593    }
3594
3595    err = mOMX->setParameter(
3596            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
3597
3598    return err;
3599}
3600
3601status_t ACodec::initNativeWindow() {
3602    if (mNativeWindow != NULL) {
3603        return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
3604    }
3605
3606    mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
3607    return OK;
3608}
3609
3610size_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
3611    size_t n = 0;
3612
3613    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
3614        const BufferInfo &info = mBuffers[portIndex].itemAt(i);
3615
3616        if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
3617            ++n;
3618        }
3619    }
3620
3621    return n;
3622}
3623
3624size_t ACodec::countBuffersOwnedByNativeWindow() const {
3625    size_t n = 0;
3626
3627    for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
3628        const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
3629
3630        if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3631            ++n;
3632        }
3633    }
3634
3635    return n;
3636}
3637
3638void ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
3639    if (mNativeWindow == NULL) {
3640        return;
3641    }
3642
3643    while (countBuffersOwnedByNativeWindow() > mNumUndequeuedBuffers
3644            && dequeueBufferFromNativeWindow() != NULL) {
3645        // these buffers will be submitted as regular buffers; account for this
3646        if (storingMetadataInDecodedBuffers() && mMetadataBuffersToSubmit > 0) {
3647            --mMetadataBuffersToSubmit;
3648        }
3649    }
3650}
3651
3652bool ACodec::allYourBuffersAreBelongToUs(
3653        OMX_U32 portIndex) {
3654    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
3655        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
3656
3657        if (info->mStatus != BufferInfo::OWNED_BY_US
3658                && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3659            ALOGV("[%s] Buffer %u on port %u still has status %d",
3660                    mComponentName.c_str(),
3661                    info->mBufferID, portIndex, info->mStatus);
3662            return false;
3663        }
3664    }
3665
3666    return true;
3667}
3668
3669bool ACodec::allYourBuffersAreBelongToUs() {
3670    return allYourBuffersAreBelongToUs(kPortIndexInput)
3671        && allYourBuffersAreBelongToUs(kPortIndexOutput);
3672}
3673
3674void ACodec::deferMessage(const sp<AMessage> &msg) {
3675    mDeferredQueue.push_back(msg);
3676}
3677
3678void ACodec::processDeferredMessages() {
3679    List<sp<AMessage> > queue = mDeferredQueue;
3680    mDeferredQueue.clear();
3681
3682    List<sp<AMessage> >::iterator it = queue.begin();
3683    while (it != queue.end()) {
3684        onMessageReceived(*it++);
3685    }
3686}
3687
3688// static
3689bool ACodec::describeDefaultColorFormat(DescribeColorFormatParams &params) {
3690    MediaImage &image = params.sMediaImage;
3691    memset(&image, 0, sizeof(image));
3692
3693    image.mType = MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
3694    image.mNumPlanes = 0;
3695
3696    const OMX_COLOR_FORMATTYPE fmt = params.eColorFormat;
3697    image.mWidth = params.nFrameWidth;
3698    image.mHeight = params.nFrameHeight;
3699
3700    // only supporting YUV420
3701    if (fmt != OMX_COLOR_FormatYUV420Planar &&
3702        fmt != OMX_COLOR_FormatYUV420PackedPlanar &&
3703        fmt != OMX_COLOR_FormatYUV420SemiPlanar &&
3704        fmt != OMX_COLOR_FormatYUV420PackedSemiPlanar &&
3705        fmt != HAL_PIXEL_FORMAT_YV12) {
3706        ALOGW("do not know color format 0x%x = %d", fmt, fmt);
3707        return false;
3708    }
3709
3710    // TEMPORARY FIX for some vendors that advertise sliceHeight as 0
3711    if (params.nStride != 0 && params.nSliceHeight == 0) {
3712        ALOGW("using sliceHeight=%u instead of what codec advertised (=0)",
3713                params.nFrameHeight);
3714        params.nSliceHeight = params.nFrameHeight;
3715    }
3716
3717    // we need stride and slice-height to be non-zero
3718    if (params.nStride == 0 || params.nSliceHeight == 0) {
3719        ALOGW("cannot describe color format 0x%x = %d with stride=%u and sliceHeight=%u",
3720                fmt, fmt, params.nStride, params.nSliceHeight);
3721        return false;
3722    }
3723
3724    // set-up YUV format
3725    image.mType = MediaImage::MEDIA_IMAGE_TYPE_YUV;
3726    image.mNumPlanes = 3;
3727    image.mBitDepth = 8;
3728    image.mPlane[image.Y].mOffset = 0;
3729    image.mPlane[image.Y].mColInc = 1;
3730    image.mPlane[image.Y].mRowInc = params.nStride;
3731    image.mPlane[image.Y].mHorizSubsampling = 1;
3732    image.mPlane[image.Y].mVertSubsampling = 1;
3733
3734    switch ((int)fmt) {
3735        case HAL_PIXEL_FORMAT_YV12:
3736            if (params.bUsingNativeBuffers) {
3737                size_t ystride = align(params.nStride, 16);
3738                size_t cstride = align(params.nStride / 2, 16);
3739                image.mPlane[image.Y].mRowInc = ystride;
3740
3741                image.mPlane[image.V].mOffset = ystride * params.nSliceHeight;
3742                image.mPlane[image.V].mColInc = 1;
3743                image.mPlane[image.V].mRowInc = cstride;
3744                image.mPlane[image.V].mHorizSubsampling = 2;
3745                image.mPlane[image.V].mVertSubsampling = 2;
3746
3747                image.mPlane[image.U].mOffset = image.mPlane[image.V].mOffset
3748                        + (cstride * params.nSliceHeight / 2);
3749                image.mPlane[image.U].mColInc = 1;
3750                image.mPlane[image.U].mRowInc = cstride;
3751                image.mPlane[image.U].mHorizSubsampling = 2;
3752                image.mPlane[image.U].mVertSubsampling = 2;
3753                break;
3754            } else {
3755                // fall through as YV12 is used for YUV420Planar by some codecs
3756            }
3757
3758        case OMX_COLOR_FormatYUV420Planar:
3759        case OMX_COLOR_FormatYUV420PackedPlanar:
3760            image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight;
3761            image.mPlane[image.U].mColInc = 1;
3762            image.mPlane[image.U].mRowInc = params.nStride / 2;
3763            image.mPlane[image.U].mHorizSubsampling = 2;
3764            image.mPlane[image.U].mVertSubsampling = 2;
3765
3766            image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset
3767                    + (params.nStride * params.nSliceHeight / 4);
3768            image.mPlane[image.V].mColInc = 1;
3769            image.mPlane[image.V].mRowInc = params.nStride / 2;
3770            image.mPlane[image.V].mHorizSubsampling = 2;
3771            image.mPlane[image.V].mVertSubsampling = 2;
3772            break;
3773
3774        case OMX_COLOR_FormatYUV420SemiPlanar:
3775            // FIXME: NV21 for sw-encoder, NV12 for decoder and hw-encoder
3776        case OMX_COLOR_FormatYUV420PackedSemiPlanar:
3777            // NV12
3778            image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight;
3779            image.mPlane[image.U].mColInc = 2;
3780            image.mPlane[image.U].mRowInc = params.nStride;
3781            image.mPlane[image.U].mHorizSubsampling = 2;
3782            image.mPlane[image.U].mVertSubsampling = 2;
3783
3784            image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset + 1;
3785            image.mPlane[image.V].mColInc = 2;
3786            image.mPlane[image.V].mRowInc = params.nStride;
3787            image.mPlane[image.V].mHorizSubsampling = 2;
3788            image.mPlane[image.V].mVertSubsampling = 2;
3789            break;
3790
3791        default:
3792            TRESPASS();
3793    }
3794    return true;
3795}
3796
3797// static
3798bool ACodec::describeColorFormat(
3799        const sp<IOMX> &omx, IOMX::node_id node,
3800        DescribeColorFormatParams &describeParams)
3801{
3802    OMX_INDEXTYPE describeColorFormatIndex;
3803    if (omx->getExtensionIndex(
3804            node, "OMX.google.android.index.describeColorFormat",
3805            &describeColorFormatIndex) != OK ||
3806        omx->getParameter(
3807            node, describeColorFormatIndex,
3808            &describeParams, sizeof(describeParams)) != OK) {
3809        return describeDefaultColorFormat(describeParams);
3810    }
3811    return describeParams.sMediaImage.mType !=
3812            MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
3813}
3814
3815// static
3816bool ACodec::isFlexibleColorFormat(
3817         const sp<IOMX> &omx, IOMX::node_id node,
3818         uint32_t colorFormat, bool usingNativeBuffers, OMX_U32 *flexibleEquivalent) {
3819    DescribeColorFormatParams describeParams;
3820    InitOMXParams(&describeParams);
3821    describeParams.eColorFormat = (OMX_COLOR_FORMATTYPE)colorFormat;
3822    // reasonable dummy values
3823    describeParams.nFrameWidth = 128;
3824    describeParams.nFrameHeight = 128;
3825    describeParams.nStride = 128;
3826    describeParams.nSliceHeight = 128;
3827    describeParams.bUsingNativeBuffers = (OMX_BOOL)usingNativeBuffers;
3828
3829    CHECK(flexibleEquivalent != NULL);
3830
3831    if (!describeColorFormat(omx, node, describeParams)) {
3832        return false;
3833    }
3834
3835    const MediaImage &img = describeParams.sMediaImage;
3836    if (img.mType == MediaImage::MEDIA_IMAGE_TYPE_YUV) {
3837        if (img.mNumPlanes != 3 ||
3838            img.mPlane[img.Y].mHorizSubsampling != 1 ||
3839            img.mPlane[img.Y].mVertSubsampling != 1) {
3840            return false;
3841        }
3842
3843        // YUV 420
3844        if (img.mPlane[img.U].mHorizSubsampling == 2
3845                && img.mPlane[img.U].mVertSubsampling == 2
3846                && img.mPlane[img.V].mHorizSubsampling == 2
3847                && img.mPlane[img.V].mVertSubsampling == 2) {
3848            // possible flexible YUV420 format
3849            if (img.mBitDepth <= 8) {
3850               *flexibleEquivalent = OMX_COLOR_FormatYUV420Flexible;
3851               return true;
3852            }
3853        }
3854    }
3855    return false;
3856}
3857
3858status_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> &notify) {
3859    const char *niceIndex = portIndex == kPortIndexInput ? "input" : "output";
3860    OMX_PARAM_PORTDEFINITIONTYPE def;
3861    InitOMXParams(&def);
3862    def.nPortIndex = portIndex;
3863
3864    status_t err = mOMX->getParameter(mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
3865    if (err != OK) {
3866        return err;
3867    }
3868
3869    if (def.eDir != (portIndex == kPortIndexOutput ? OMX_DirOutput : OMX_DirInput)) {
3870        ALOGE("unexpected dir: %s(%d) on %s port", asString(def.eDir), def.eDir, niceIndex);
3871        return BAD_VALUE;
3872    }
3873
3874    switch (def.eDomain) {
3875        case OMX_PortDomainVideo:
3876        {
3877            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
3878            switch ((int)videoDef->eCompressionFormat) {
3879                case OMX_VIDEO_CodingUnused:
3880                {
3881                    CHECK(mIsEncoder ^ (portIndex == kPortIndexOutput));
3882                    notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
3883
3884                    notify->setInt32("stride", videoDef->nStride);
3885                    notify->setInt32("slice-height", videoDef->nSliceHeight);
3886                    notify->setInt32("color-format", videoDef->eColorFormat);
3887
3888                    if (mNativeWindow == NULL) {
3889                        DescribeColorFormatParams describeParams;
3890                        InitOMXParams(&describeParams);
3891                        describeParams.eColorFormat = videoDef->eColorFormat;
3892                        describeParams.nFrameWidth = videoDef->nFrameWidth;
3893                        describeParams.nFrameHeight = videoDef->nFrameHeight;
3894                        describeParams.nStride = videoDef->nStride;
3895                        describeParams.nSliceHeight = videoDef->nSliceHeight;
3896                        describeParams.bUsingNativeBuffers = OMX_FALSE;
3897
3898                        if (describeColorFormat(mOMX, mNode, describeParams)) {
3899                            notify->setBuffer(
3900                                    "image-data",
3901                                    ABuffer::CreateAsCopy(
3902                                            &describeParams.sMediaImage,
3903                                            sizeof(describeParams.sMediaImage)));
3904
3905                            MediaImage *img = &describeParams.sMediaImage;
3906                            ALOGV("[%s] MediaImage { F(%zux%zu) @%zu+%zu+%zu @%zu+%zu+%zu @%zu+%zu+%zu }",
3907                                    mComponentName.c_str(), img->mWidth, img->mHeight,
3908                                    img->mPlane[0].mOffset, img->mPlane[0].mColInc, img->mPlane[0].mRowInc,
3909                                    img->mPlane[1].mOffset, img->mPlane[1].mColInc, img->mPlane[1].mRowInc,
3910                                    img->mPlane[2].mOffset, img->mPlane[2].mColInc, img->mPlane[2].mRowInc);
3911                        }
3912                    }
3913
3914                    if (portIndex != kPortIndexOutput) {
3915                        // TODO: also get input crop
3916                        break;
3917                    }
3918
3919                    OMX_CONFIG_RECTTYPE rect;
3920                    InitOMXParams(&rect);
3921                    rect.nPortIndex = portIndex;
3922
3923                    if (mOMX->getConfig(
3924                                mNode,
3925                                (portIndex == kPortIndexOutput ?
3926                                        OMX_IndexConfigCommonOutputCrop :
3927                                        OMX_IndexConfigCommonInputCrop),
3928                                &rect, sizeof(rect)) != OK) {
3929                        rect.nLeft = 0;
3930                        rect.nTop = 0;
3931                        rect.nWidth = videoDef->nFrameWidth;
3932                        rect.nHeight = videoDef->nFrameHeight;
3933                    }
3934
3935                    if (rect.nLeft < 0 ||
3936                        rect.nTop < 0 ||
3937                        rect.nLeft + rect.nWidth > videoDef->nFrameWidth ||
3938                        rect.nTop + rect.nHeight > videoDef->nFrameHeight) {
3939                        ALOGE("Wrong cropped rect (%d, %d) - (%u, %u) vs. frame (%u, %u)",
3940                                rect.nLeft, rect.nTop,
3941                                rect.nLeft + rect.nWidth, rect.nTop + rect.nHeight,
3942                                videoDef->nFrameWidth, videoDef->nFrameHeight);
3943                        return BAD_VALUE;
3944                    }
3945
3946                    notify->setRect(
3947                            "crop",
3948                            rect.nLeft,
3949                            rect.nTop,
3950                            rect.nLeft + rect.nWidth - 1,
3951                            rect.nTop + rect.nHeight - 1);
3952
3953                    break;
3954                }
3955
3956                case OMX_VIDEO_CodingVP8:
3957                case OMX_VIDEO_CodingVP9:
3958                {
3959                    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
3960                    InitOMXParams(&vp8type);
3961                    vp8type.nPortIndex = kPortIndexOutput;
3962                    status_t err = mOMX->getParameter(
3963                            mNode,
3964                            (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
3965                            &vp8type,
3966                            sizeof(vp8type));
3967
3968                    if (err == OK) {
3969                        AString tsSchema = "none";
3970                        if (vp8type.eTemporalPattern
3971                                == OMX_VIDEO_VPXTemporalLayerPatternWebRTC) {
3972                            switch (vp8type.nTemporalLayerCount) {
3973                                case 1:
3974                                {
3975                                    tsSchema = "webrtc.vp8.1-layer";
3976                                    break;
3977                                }
3978                                case 2:
3979                                {
3980                                    tsSchema = "webrtc.vp8.2-layer";
3981                                    break;
3982                                }
3983                                case 3:
3984                                {
3985                                    tsSchema = "webrtc.vp8.3-layer";
3986                                    break;
3987                                }
3988                                default:
3989                                {
3990                                    break;
3991                                }
3992                            }
3993                        }
3994                        notify->setString("ts-schema", tsSchema);
3995                    }
3996                    // Fall through to set up mime.
3997                }
3998
3999                default:
4000                {
4001                    if (mIsEncoder ^ (portIndex == kPortIndexOutput)) {
4002                        // should be CodingUnused
4003                        ALOGE("Raw port video compression format is %s(%d)",
4004                                asString(videoDef->eCompressionFormat),
4005                                videoDef->eCompressionFormat);
4006                        return BAD_VALUE;
4007                    }
4008                    AString mime;
4009                    if (GetMimeTypeForVideoCoding(
4010                        videoDef->eCompressionFormat, &mime) != OK) {
4011                        notify->setString("mime", "application/octet-stream");
4012                    } else {
4013                        notify->setString("mime", mime.c_str());
4014                    }
4015                    break;
4016                }
4017            }
4018            notify->setInt32("width", videoDef->nFrameWidth);
4019            notify->setInt32("height", videoDef->nFrameHeight);
4020            ALOGV("[%s] %s format is %s", mComponentName.c_str(),
4021                    portIndex == kPortIndexInput ? "input" : "output",
4022                    notify->debugString().c_str());
4023
4024            break;
4025        }
4026
4027        case OMX_PortDomainAudio:
4028        {
4029            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
4030
4031            switch ((int)audioDef->eEncoding) {
4032                case OMX_AUDIO_CodingPCM:
4033                {
4034                    OMX_AUDIO_PARAM_PCMMODETYPE params;
4035                    InitOMXParams(&params);
4036                    params.nPortIndex = portIndex;
4037
4038                    err = mOMX->getParameter(
4039                            mNode, OMX_IndexParamAudioPcm, &params, sizeof(params));
4040                    if (err != OK) {
4041                        return err;
4042                    }
4043
4044                    if (params.nChannels <= 0
4045                            || (params.nChannels != 1 && !params.bInterleaved)
4046                            || params.nBitPerSample != 16u
4047                            || params.eNumData != OMX_NumericalDataSigned
4048                            || params.ePCMMode != OMX_AUDIO_PCMModeLinear) {
4049                        ALOGE("unsupported PCM port: %u channels%s, %u-bit, %s(%d), %s(%d) mode ",
4050                                params.nChannels,
4051                                params.bInterleaved ? " interleaved" : "",
4052                                params.nBitPerSample,
4053                                asString(params.eNumData), params.eNumData,
4054                                asString(params.ePCMMode), params.ePCMMode);
4055                        return FAILED_TRANSACTION;
4056                    }
4057
4058                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
4059                    notify->setInt32("channel-count", params.nChannels);
4060                    notify->setInt32("sample-rate", params.nSamplingRate);
4061
4062                    if (mChannelMaskPresent) {
4063                        notify->setInt32("channel-mask", mChannelMask);
4064                    }
4065                    break;
4066                }
4067
4068                case OMX_AUDIO_CodingAAC:
4069                {
4070                    OMX_AUDIO_PARAM_AACPROFILETYPE params;
4071                    InitOMXParams(&params);
4072                    params.nPortIndex = portIndex;
4073
4074                    err = mOMX->getParameter(
4075                            mNode, OMX_IndexParamAudioAac, &params, sizeof(params));
4076                    if (err != OK) {
4077                        return err;
4078                    }
4079
4080                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
4081                    notify->setInt32("channel-count", params.nChannels);
4082                    notify->setInt32("sample-rate", params.nSampleRate);
4083                    break;
4084                }
4085
4086                case OMX_AUDIO_CodingAMR:
4087                {
4088                    OMX_AUDIO_PARAM_AMRTYPE params;
4089                    InitOMXParams(&params);
4090                    params.nPortIndex = portIndex;
4091
4092                    err = mOMX->getParameter(
4093                            mNode, OMX_IndexParamAudioAmr, &params, sizeof(params));
4094                    if (err != OK) {
4095                        return err;
4096                    }
4097
4098                    notify->setInt32("channel-count", 1);
4099                    if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) {
4100                        notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_WB);
4101                        notify->setInt32("sample-rate", 16000);
4102                    } else {
4103                        notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
4104                        notify->setInt32("sample-rate", 8000);
4105                    }
4106                    break;
4107                }
4108
4109                case OMX_AUDIO_CodingFLAC:
4110                {
4111                    OMX_AUDIO_PARAM_FLACTYPE params;
4112                    InitOMXParams(&params);
4113                    params.nPortIndex = portIndex;
4114
4115                    err = mOMX->getParameter(
4116                            mNode, OMX_IndexParamAudioFlac, &params, sizeof(params));
4117                    if (err != OK) {
4118                        return err;
4119                    }
4120
4121                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC);
4122                    notify->setInt32("channel-count", params.nChannels);
4123                    notify->setInt32("sample-rate", params.nSampleRate);
4124                    break;
4125                }
4126
4127                case OMX_AUDIO_CodingMP3:
4128                {
4129                    OMX_AUDIO_PARAM_MP3TYPE params;
4130                    InitOMXParams(&params);
4131                    params.nPortIndex = portIndex;
4132
4133                    err = mOMX->getParameter(
4134                            mNode, OMX_IndexParamAudioMp3, &params, sizeof(params));
4135                    if (err != OK) {
4136                        return err;
4137                    }
4138
4139                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MPEG);
4140                    notify->setInt32("channel-count", params.nChannels);
4141                    notify->setInt32("sample-rate", params.nSampleRate);
4142                    break;
4143                }
4144
4145                case OMX_AUDIO_CodingVORBIS:
4146                {
4147                    OMX_AUDIO_PARAM_VORBISTYPE params;
4148                    InitOMXParams(&params);
4149                    params.nPortIndex = portIndex;
4150
4151                    err = mOMX->getParameter(
4152                            mNode, OMX_IndexParamAudioVorbis, &params, sizeof(params));
4153                    if (err != OK) {
4154                        return err;
4155                    }
4156
4157                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_VORBIS);
4158                    notify->setInt32("channel-count", params.nChannels);
4159                    notify->setInt32("sample-rate", params.nSampleRate);
4160                    break;
4161                }
4162
4163                case OMX_AUDIO_CodingAndroidAC3:
4164                {
4165                    OMX_AUDIO_PARAM_ANDROID_AC3TYPE params;
4166                    InitOMXParams(&params);
4167                    params.nPortIndex = portIndex;
4168
4169                    err = mOMX->getParameter(
4170                            mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
4171                            &params, sizeof(params));
4172                    if (err != OK) {
4173                        return err;
4174                    }
4175
4176                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AC3);
4177                    notify->setInt32("channel-count", params.nChannels);
4178                    notify->setInt32("sample-rate", params.nSampleRate);
4179                    break;
4180                }
4181
4182                case OMX_AUDIO_CodingAndroidEAC3:
4183                {
4184                    OMX_AUDIO_PARAM_ANDROID_EAC3TYPE params;
4185                    InitOMXParams(&params);
4186                    params.nPortIndex = portIndex;
4187
4188                    err = mOMX->getParameter(
4189                            mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
4190                            &params, sizeof(params));
4191                    if (err != OK) {
4192                        return err;
4193                    }
4194
4195                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_EAC3);
4196                    notify->setInt32("channel-count", params.nChannels);
4197                    notify->setInt32("sample-rate", params.nSampleRate);
4198                    break;
4199                }
4200
4201                case OMX_AUDIO_CodingAndroidOPUS:
4202                {
4203                    OMX_AUDIO_PARAM_ANDROID_OPUSTYPE params;
4204                    InitOMXParams(&params);
4205                    params.nPortIndex = portIndex;
4206
4207                    err = mOMX->getParameter(
4208                            mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus,
4209                            &params, sizeof(params));
4210                    if (err != OK) {
4211                        return err;
4212                    }
4213
4214                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_OPUS);
4215                    notify->setInt32("channel-count", params.nChannels);
4216                    notify->setInt32("sample-rate", params.nSampleRate);
4217                    break;
4218                }
4219
4220                case OMX_AUDIO_CodingG711:
4221                {
4222                    OMX_AUDIO_PARAM_PCMMODETYPE params;
4223                    InitOMXParams(&params);
4224                    params.nPortIndex = portIndex;
4225
4226                    err = mOMX->getParameter(
4227                            mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioPcm, &params, sizeof(params));
4228                    if (err != OK) {
4229                        return err;
4230                    }
4231
4232                    const char *mime = NULL;
4233                    if (params.ePCMMode == OMX_AUDIO_PCMModeMULaw) {
4234                        mime = MEDIA_MIMETYPE_AUDIO_G711_MLAW;
4235                    } else if (params.ePCMMode == OMX_AUDIO_PCMModeALaw) {
4236                        mime = MEDIA_MIMETYPE_AUDIO_G711_ALAW;
4237                    } else { // params.ePCMMode == OMX_AUDIO_PCMModeLinear
4238                        mime = MEDIA_MIMETYPE_AUDIO_RAW;
4239                    }
4240                    notify->setString("mime", mime);
4241                    notify->setInt32("channel-count", params.nChannels);
4242                    notify->setInt32("sample-rate", params.nSamplingRate);
4243                    break;
4244                }
4245
4246                case OMX_AUDIO_CodingGSMFR:
4247                {
4248                    OMX_AUDIO_PARAM_PCMMODETYPE params;
4249                    InitOMXParams(&params);
4250                    params.nPortIndex = portIndex;
4251
4252                    err = mOMX->getParameter(
4253                                mNode, OMX_IndexParamAudioPcm, &params, sizeof(params));
4254                    if (err != OK) {
4255                        return err;
4256                    }
4257
4258                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MSGSM);
4259                    notify->setInt32("channel-count", params.nChannels);
4260                    notify->setInt32("sample-rate", params.nSamplingRate);
4261                    break;
4262                }
4263
4264                default:
4265                    ALOGE("Unsupported audio coding: %s(%d)\n",
4266                            asString(audioDef->eEncoding), audioDef->eEncoding);
4267                    return BAD_TYPE;
4268            }
4269            break;
4270        }
4271
4272        default:
4273            ALOGE("Unsupported domain: %s(%d)", asString(def.eDomain), def.eDomain);
4274            return BAD_TYPE;
4275    }
4276
4277    return OK;
4278}
4279
4280void ACodec::sendFormatChange(const sp<AMessage> &reply) {
4281    sp<AMessage> notify = mBaseOutputFormat->dup();
4282    notify->setInt32("what", kWhatOutputFormatChanged);
4283
4284    if (getPortFormat(kPortIndexOutput, notify) != OK) {
4285        ALOGE("[%s] Failed to get port format to send format change", mComponentName.c_str());
4286        return;
4287    }
4288
4289    AString mime;
4290    CHECK(notify->findString("mime", &mime));
4291
4292    int32_t left, top, right, bottom;
4293    if (mime == MEDIA_MIMETYPE_VIDEO_RAW &&
4294        mNativeWindow != NULL &&
4295        notify->findRect("crop", &left, &top, &right, &bottom)) {
4296        // notify renderer of the crop change
4297        // NOTE: native window uses extended right-bottom coordinate
4298        reply->setRect("crop", left, top, right + 1, bottom + 1);
4299    } else if (mime == MEDIA_MIMETYPE_AUDIO_RAW &&
4300               (mEncoderDelay || mEncoderPadding)) {
4301        int32_t channelCount;
4302        CHECK(notify->findInt32("channel-count", &channelCount));
4303        size_t frameSize = channelCount * sizeof(int16_t);
4304        if (mSkipCutBuffer != NULL) {
4305            size_t prevbufsize = mSkipCutBuffer->size();
4306            if (prevbufsize != 0) {
4307                ALOGW("Replacing SkipCutBuffer holding %zu bytes", prevbufsize);
4308            }
4309        }
4310        mSkipCutBuffer = new SkipCutBuffer(
4311                mEncoderDelay * frameSize,
4312                mEncoderPadding * frameSize);
4313    }
4314
4315    notify->post();
4316
4317    mSentFormat = true;
4318}
4319
4320void ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
4321    sp<AMessage> notify = mNotify->dup();
4322    notify->setInt32("what", CodecBase::kWhatError);
4323    ALOGE("signalError(omxError %#x, internalError %d)", error, internalError);
4324
4325    if (internalError == UNKNOWN_ERROR) { // find better error code
4326        const status_t omxStatus = statusFromOMXError(error);
4327        if (omxStatus != 0) {
4328            internalError = omxStatus;
4329        } else {
4330            ALOGW("Invalid OMX error %#x", error);
4331        }
4332    }
4333    notify->setInt32("err", internalError);
4334    notify->setInt32("actionCode", ACTION_CODE_FATAL); // could translate from OMX error.
4335    notify->post();
4336}
4337
4338////////////////////////////////////////////////////////////////////////////////
4339
4340ACodec::PortDescription::PortDescription() {
4341}
4342
4343status_t ACodec::requestIDRFrame() {
4344    if (!mIsEncoder) {
4345        return ERROR_UNSUPPORTED;
4346    }
4347
4348    OMX_CONFIG_INTRAREFRESHVOPTYPE params;
4349    InitOMXParams(&params);
4350
4351    params.nPortIndex = kPortIndexOutput;
4352    params.IntraRefreshVOP = OMX_TRUE;
4353
4354    return mOMX->setConfig(
4355            mNode,
4356            OMX_IndexConfigVideoIntraVOPRefresh,
4357            &params,
4358            sizeof(params));
4359}
4360
4361void ACodec::PortDescription::addBuffer(
4362        IOMX::buffer_id id, const sp<ABuffer> &buffer) {
4363    mBufferIDs.push_back(id);
4364    mBuffers.push_back(buffer);
4365}
4366
4367size_t ACodec::PortDescription::countBuffers() {
4368    return mBufferIDs.size();
4369}
4370
4371IOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const {
4372    return mBufferIDs.itemAt(index);
4373}
4374
4375sp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const {
4376    return mBuffers.itemAt(index);
4377}
4378
4379////////////////////////////////////////////////////////////////////////////////
4380
4381ACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
4382    : AState(parentState),
4383      mCodec(codec) {
4384}
4385
4386ACodec::BaseState::PortMode ACodec::BaseState::getPortMode(
4387        OMX_U32 /* portIndex */) {
4388    return KEEP_BUFFERS;
4389}
4390
4391bool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
4392    switch (msg->what()) {
4393        case kWhatInputBufferFilled:
4394        {
4395            onInputBufferFilled(msg);
4396            break;
4397        }
4398
4399        case kWhatOutputBufferDrained:
4400        {
4401            onOutputBufferDrained(msg);
4402            break;
4403        }
4404
4405        case ACodec::kWhatOMXMessage:
4406        {
4407            return onOMXMessage(msg);
4408        }
4409
4410        case ACodec::kWhatSetSurface:
4411        {
4412            sp<AReplyToken> replyID;
4413            CHECK(msg->senderAwaitsResponse(&replyID));
4414
4415            sp<RefBase> obj;
4416            CHECK(msg->findObject("surface", &obj));
4417
4418            status_t err =
4419                ADebug::isExperimentEnabled("legacy-setsurface") ? BAD_VALUE :
4420                        mCodec->handleSetSurface(static_cast<Surface *>(obj.get()));
4421
4422            sp<AMessage> response = new AMessage;
4423            response->setInt32("err", err);
4424            response->postReply(replyID);
4425            break;
4426        }
4427
4428        case ACodec::kWhatCreateInputSurface:
4429        case ACodec::kWhatSetInputSurface:
4430        case ACodec::kWhatSignalEndOfInputStream:
4431        {
4432            // This may result in an app illegal state exception.
4433            ALOGE("Message 0x%x was not handled", msg->what());
4434            mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
4435            return true;
4436        }
4437
4438        case ACodec::kWhatOMXDied:
4439        {
4440            // This will result in kFlagSawMediaServerDie handling in MediaCodec.
4441            ALOGE("OMX/mediaserver died, signalling error!");
4442            mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT);
4443            break;
4444        }
4445
4446        case ACodec::kWhatReleaseCodecInstance:
4447        {
4448            ALOGI("[%s] forcing the release of codec",
4449                    mCodec->mComponentName.c_str());
4450            status_t err = mCodec->mOMX->freeNode(mCodec->mNode);
4451            ALOGE_IF("[%s] failed to release codec instance: err=%d",
4452                       mCodec->mComponentName.c_str(), err);
4453            sp<AMessage> notify = mCodec->mNotify->dup();
4454            notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
4455            notify->post();
4456            break;
4457        }
4458
4459        default:
4460            return false;
4461    }
4462
4463    return true;
4464}
4465
4466bool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
4467    int32_t type;
4468    CHECK(msg->findInt32("type", &type));
4469
4470    // there is a possibility that this is an outstanding message for a
4471    // codec that we have already destroyed
4472    if (mCodec->mNode == 0) {
4473        ALOGI("ignoring message as already freed component: %s",
4474                msg->debugString().c_str());
4475        return true;
4476    }
4477
4478    IOMX::node_id nodeID;
4479    CHECK(msg->findInt32("node", (int32_t*)&nodeID));
4480    if (nodeID != mCodec->mNode) {
4481        ALOGE("Unexpected message for nodeID: %u, should have been %u", nodeID, mCodec->mNode);
4482        return false;
4483    }
4484
4485    switch (type) {
4486        case omx_message::EVENT:
4487        {
4488            int32_t event, data1, data2;
4489            CHECK(msg->findInt32("event", &event));
4490            CHECK(msg->findInt32("data1", &data1));
4491            CHECK(msg->findInt32("data2", &data2));
4492
4493            if (event == OMX_EventCmdComplete
4494                    && data1 == OMX_CommandFlush
4495                    && data2 == (int32_t)OMX_ALL) {
4496                // Use of this notification is not consistent across
4497                // implementations. We'll drop this notification and rely
4498                // on flush-complete notifications on the individual port
4499                // indices instead.
4500
4501                return true;
4502            }
4503
4504            return onOMXEvent(
4505                    static_cast<OMX_EVENTTYPE>(event),
4506                    static_cast<OMX_U32>(data1),
4507                    static_cast<OMX_U32>(data2));
4508        }
4509
4510        case omx_message::EMPTY_BUFFER_DONE:
4511        {
4512            IOMX::buffer_id bufferID;
4513            int32_t fenceFd;
4514
4515            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
4516            CHECK(msg->findInt32("fence_fd", &fenceFd));
4517
4518            return onOMXEmptyBufferDone(bufferID, fenceFd);
4519        }
4520
4521        case omx_message::FILL_BUFFER_DONE:
4522        {
4523            IOMX::buffer_id bufferID;
4524            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
4525
4526            int32_t rangeOffset, rangeLength, flags, fenceFd;
4527            int64_t timeUs;
4528
4529            CHECK(msg->findInt32("range_offset", &rangeOffset));
4530            CHECK(msg->findInt32("range_length", &rangeLength));
4531            CHECK(msg->findInt32("flags", &flags));
4532            CHECK(msg->findInt64("timestamp", &timeUs));
4533            CHECK(msg->findInt32("fence_fd", &fenceFd));
4534
4535            return onOMXFillBufferDone(
4536                    bufferID,
4537                    (size_t)rangeOffset, (size_t)rangeLength,
4538                    (OMX_U32)flags,
4539                    timeUs,
4540                    fenceFd);
4541        }
4542
4543        default:
4544            ALOGE("Unexpected message type: %d", type);
4545            return false;
4546    }
4547}
4548
4549bool ACodec::BaseState::onOMXEvent(
4550        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4551    if (event != OMX_EventError) {
4552        ALOGV("[%s] EVENT(%d, 0x%08x, 0x%08x)",
4553             mCodec->mComponentName.c_str(), event, data1, data2);
4554
4555        return false;
4556    }
4557
4558    ALOGE("[%s] ERROR(0x%08x)", mCodec->mComponentName.c_str(), data1);
4559
4560    // verify OMX component sends back an error we expect.
4561    OMX_ERRORTYPE omxError = (OMX_ERRORTYPE)data1;
4562    if (!isOMXError(omxError)) {
4563        ALOGW("Invalid OMX error %#x", omxError);
4564        omxError = OMX_ErrorUndefined;
4565    }
4566    mCodec->signalError(omxError);
4567
4568    return true;
4569}
4570
4571bool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID, int fenceFd) {
4572    ALOGV("[%s] onOMXEmptyBufferDone %u",
4573         mCodec->mComponentName.c_str(), bufferID);
4574
4575    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
4576    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
4577    if (status != BufferInfo::OWNED_BY_COMPONENT) {
4578        ALOGE("Wrong ownership in EBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
4579        mCodec->dumpBuffers(kPortIndexInput);
4580        if (fenceFd >= 0) {
4581            ::close(fenceFd);
4582        }
4583        return false;
4584    }
4585    info->mStatus = BufferInfo::OWNED_BY_US;
4586
4587    // input buffers cannot take fences, so wait for any fence now
4588    (void)mCodec->waitForFence(fenceFd, "onOMXEmptyBufferDone");
4589    fenceFd = -1;
4590
4591    // still save fence for completeness
4592    info->setWriteFence(fenceFd, "onOMXEmptyBufferDone");
4593
4594    // We're in "store-metadata-in-buffers" mode, the underlying
4595    // OMX component had access to data that's implicitly refcounted
4596    // by this "MediaBuffer" object. Now that the OMX component has
4597    // told us that it's done with the input buffer, we can decrement
4598    // the mediaBuffer's reference count.
4599    info->mData->setMediaBufferBase(NULL);
4600
4601    PortMode mode = getPortMode(kPortIndexInput);
4602
4603    switch (mode) {
4604        case KEEP_BUFFERS:
4605            break;
4606
4607        case RESUBMIT_BUFFERS:
4608            postFillThisBuffer(info);
4609            break;
4610
4611        case FREE_BUFFERS:
4612        default:
4613            ALOGE("SHOULD NOT REACH HERE: cannot free empty output buffers");
4614            return false;
4615    }
4616
4617    return true;
4618}
4619
4620void ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
4621    if (mCodec->mPortEOS[kPortIndexInput]) {
4622        return;
4623    }
4624
4625    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
4626
4627    sp<AMessage> notify = mCodec->mNotify->dup();
4628    notify->setInt32("what", CodecBase::kWhatFillThisBuffer);
4629    notify->setInt32("buffer-id", info->mBufferID);
4630
4631    info->mData->meta()->clear();
4632    notify->setBuffer("buffer", info->mData);
4633
4634    sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec);
4635    reply->setInt32("buffer-id", info->mBufferID);
4636
4637    notify->setMessage("reply", reply);
4638
4639    notify->post();
4640
4641    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
4642}
4643
4644void ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
4645    IOMX::buffer_id bufferID;
4646    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
4647    sp<ABuffer> buffer;
4648    int32_t err = OK;
4649    bool eos = false;
4650    PortMode mode = getPortMode(kPortIndexInput);
4651
4652    if (!msg->findBuffer("buffer", &buffer)) {
4653        /* these are unfilled buffers returned by client */
4654        CHECK(msg->findInt32("err", &err));
4655
4656        if (err == OK) {
4657            /* buffers with no errors are returned on MediaCodec.flush */
4658            mode = KEEP_BUFFERS;
4659        } else {
4660            ALOGV("[%s] saw error %d instead of an input buffer",
4661                 mCodec->mComponentName.c_str(), err);
4662            eos = true;
4663        }
4664
4665        buffer.clear();
4666    }
4667
4668    int32_t tmp;
4669    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
4670        eos = true;
4671        err = ERROR_END_OF_STREAM;
4672    }
4673
4674    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
4675    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
4676    if (status != BufferInfo::OWNED_BY_UPSTREAM) {
4677        ALOGE("Wrong ownership in IBF: %s(%d) buffer #%u", _asString(status), status, bufferID);
4678        mCodec->dumpBuffers(kPortIndexInput);
4679        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
4680        return;
4681    }
4682
4683    info->mStatus = BufferInfo::OWNED_BY_US;
4684
4685    switch (mode) {
4686        case KEEP_BUFFERS:
4687        {
4688            if (eos) {
4689                if (!mCodec->mPortEOS[kPortIndexInput]) {
4690                    mCodec->mPortEOS[kPortIndexInput] = true;
4691                    mCodec->mInputEOSResult = err;
4692                }
4693            }
4694            break;
4695        }
4696
4697        case RESUBMIT_BUFFERS:
4698        {
4699            if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
4700                int64_t timeUs;
4701                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
4702
4703                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
4704
4705                int32_t isCSD;
4706                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
4707                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
4708                }
4709
4710                if (eos) {
4711                    flags |= OMX_BUFFERFLAG_EOS;
4712                }
4713
4714                if (buffer != info->mData) {
4715                    ALOGV("[%s] Needs to copy input data for buffer %u. (%p != %p)",
4716                         mCodec->mComponentName.c_str(),
4717                         bufferID,
4718                         buffer.get(), info->mData.get());
4719
4720                    if (buffer->size() > info->mData->capacity()) {
4721                        ALOGE("data size (%zu) is greated than buffer capacity (%zu)",
4722                                buffer->size(),           // this is the data received
4723                                info->mData->capacity()); // this is out buffer size
4724                        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
4725                        return;
4726                    }
4727                    memcpy(info->mData->data(), buffer->data(), buffer->size());
4728                }
4729
4730                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
4731                    ALOGV("[%s] calling emptyBuffer %u w/ codec specific data",
4732                         mCodec->mComponentName.c_str(), bufferID);
4733                } else if (flags & OMX_BUFFERFLAG_EOS) {
4734                    ALOGV("[%s] calling emptyBuffer %u w/ EOS",
4735                         mCodec->mComponentName.c_str(), bufferID);
4736                } else {
4737#if TRACK_BUFFER_TIMING
4738                    ALOGI("[%s] calling emptyBuffer %u w/ time %lld us",
4739                         mCodec->mComponentName.c_str(), bufferID, (long long)timeUs);
4740#else
4741                    ALOGV("[%s] calling emptyBuffer %u w/ time %lld us",
4742                         mCodec->mComponentName.c_str(), bufferID, (long long)timeUs);
4743#endif
4744                }
4745
4746#if TRACK_BUFFER_TIMING
4747                ACodec::BufferStats stats;
4748                stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
4749                stats.mFillBufferDoneTimeUs = -1ll;
4750                mCodec->mBufferStats.add(timeUs, stats);
4751#endif
4752
4753                if (mCodec->storingMetadataInDecodedBuffers()) {
4754                    // try to submit an output buffer for each input buffer
4755                    PortMode outputMode = getPortMode(kPortIndexOutput);
4756
4757                    ALOGV("MetadataBuffersToSubmit=%u portMode=%s",
4758                            mCodec->mMetadataBuffersToSubmit,
4759                            (outputMode == FREE_BUFFERS ? "FREE" :
4760                             outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
4761                    if (outputMode == RESUBMIT_BUFFERS) {
4762                        mCodec->submitOutputMetadataBuffer();
4763                    }
4764                }
4765                info->checkReadFence("onInputBufferFilled");
4766                status_t err2 = mCodec->mOMX->emptyBuffer(
4767                    mCodec->mNode,
4768                    bufferID,
4769                    0,
4770                    buffer->size(),
4771                    flags,
4772                    timeUs,
4773                    info->mFenceFd);
4774                info->mFenceFd = -1;
4775                if (err2 != OK) {
4776                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err2));
4777                    return;
4778                }
4779                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4780
4781                if (!eos && err == OK) {
4782                    getMoreInputDataIfPossible();
4783                } else {
4784                    ALOGV("[%s] Signalled EOS (%d) on the input port",
4785                         mCodec->mComponentName.c_str(), err);
4786
4787                    mCodec->mPortEOS[kPortIndexInput] = true;
4788                    mCodec->mInputEOSResult = err;
4789                }
4790            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
4791                if (err != OK && err != ERROR_END_OF_STREAM) {
4792                    ALOGV("[%s] Signalling EOS on the input port due to error %d",
4793                         mCodec->mComponentName.c_str(), err);
4794                } else {
4795                    ALOGV("[%s] Signalling EOS on the input port",
4796                         mCodec->mComponentName.c_str());
4797                }
4798
4799                ALOGV("[%s] calling emptyBuffer %u signalling EOS",
4800                     mCodec->mComponentName.c_str(), bufferID);
4801
4802                info->checkReadFence("onInputBufferFilled");
4803                status_t err2 = mCodec->mOMX->emptyBuffer(
4804                        mCodec->mNode,
4805                        bufferID,
4806                        0,
4807                        0,
4808                        OMX_BUFFERFLAG_EOS,
4809                        0,
4810                        info->mFenceFd);
4811                info->mFenceFd = -1;
4812                if (err2 != OK) {
4813                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err2));
4814                    return;
4815                }
4816                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4817
4818                mCodec->mPortEOS[kPortIndexInput] = true;
4819                mCodec->mInputEOSResult = err;
4820            }
4821            break;
4822        }
4823
4824        case FREE_BUFFERS:
4825            break;
4826
4827        default:
4828            ALOGE("invalid port mode: %d", mode);
4829            break;
4830    }
4831}
4832
4833void ACodec::BaseState::getMoreInputDataIfPossible() {
4834    if (mCodec->mPortEOS[kPortIndexInput]) {
4835        return;
4836    }
4837
4838    BufferInfo *eligible = NULL;
4839
4840    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
4841        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
4842
4843#if 0
4844        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
4845            // There's already a "read" pending.
4846            return;
4847        }
4848#endif
4849
4850        if (info->mStatus == BufferInfo::OWNED_BY_US) {
4851            eligible = info;
4852        }
4853    }
4854
4855    if (eligible == NULL) {
4856        return;
4857    }
4858
4859    postFillThisBuffer(eligible);
4860}
4861
4862bool ACodec::BaseState::onOMXFillBufferDone(
4863        IOMX::buffer_id bufferID,
4864        size_t rangeOffset, size_t rangeLength,
4865        OMX_U32 flags,
4866        int64_t timeUs,
4867        int fenceFd) {
4868    ALOGV("[%s] onOMXFillBufferDone %u time %" PRId64 " us, flags = 0x%08x",
4869         mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
4870
4871    ssize_t index;
4872    status_t err= OK;
4873
4874#if TRACK_BUFFER_TIMING
4875    index = mCodec->mBufferStats.indexOfKey(timeUs);
4876    if (index >= 0) {
4877        ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
4878        stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
4879
4880        ALOGI("frame PTS %lld: %lld",
4881                timeUs,
4882                stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
4883
4884        mCodec->mBufferStats.removeItemsAt(index);
4885        stats = NULL;
4886    }
4887#endif
4888
4889    BufferInfo *info =
4890        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
4891    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
4892    if (status != BufferInfo::OWNED_BY_COMPONENT) {
4893        ALOGE("Wrong ownership in FBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
4894        mCodec->dumpBuffers(kPortIndexOutput);
4895        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
4896        if (fenceFd >= 0) {
4897            ::close(fenceFd);
4898        }
4899        return true;
4900    }
4901
4902    info->mDequeuedAt = ++mCodec->mDequeueCounter;
4903    info->mStatus = BufferInfo::OWNED_BY_US;
4904
4905    // byte buffers cannot take fences, so wait for any fence now
4906    if (mCodec->mNativeWindow == NULL) {
4907        (void)mCodec->waitForFence(fenceFd, "onOMXFillBufferDone");
4908        fenceFd = -1;
4909    }
4910    info->setReadFence(fenceFd, "onOMXFillBufferDone");
4911
4912    PortMode mode = getPortMode(kPortIndexOutput);
4913
4914    switch (mode) {
4915        case KEEP_BUFFERS:
4916            break;
4917
4918        case RESUBMIT_BUFFERS:
4919        {
4920            if (rangeLength == 0 && (!(flags & OMX_BUFFERFLAG_EOS)
4921                    || mCodec->mPortEOS[kPortIndexOutput])) {
4922                ALOGV("[%s] calling fillBuffer %u",
4923                     mCodec->mComponentName.c_str(), info->mBufferID);
4924
4925                err = mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID, info->mFenceFd);
4926                info->mFenceFd = -1;
4927                if (err != OK) {
4928                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
4929                    return true;
4930                }
4931
4932                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4933                break;
4934            }
4935
4936            sp<AMessage> reply =
4937                new AMessage(kWhatOutputBufferDrained, mCodec);
4938
4939            if (!mCodec->mSentFormat && rangeLength > 0) {
4940                mCodec->sendFormatChange(reply);
4941            }
4942            if (mCodec->usingMetadataOnEncoderOutput()) {
4943                native_handle_t *handle = NULL;
4944                VideoGrallocMetadata &grallocMeta = *(VideoGrallocMetadata *)info->mData->data();
4945                VideoNativeMetadata &nativeMeta = *(VideoNativeMetadata *)info->mData->data();
4946                if (info->mData->size() >= sizeof(grallocMeta)
4947                        && grallocMeta.eType == kMetadataBufferTypeGrallocSource) {
4948                    handle = (native_handle_t *)grallocMeta.pHandle;
4949                } else if (info->mData->size() >= sizeof(nativeMeta)
4950                        && nativeMeta.eType == kMetadataBufferTypeANWBuffer) {
4951                    handle = (native_handle_t *)nativeMeta.pBuffer->handle;
4952                }
4953                info->mData->meta()->setPointer("handle", handle);
4954                info->mData->meta()->setInt32("rangeOffset", rangeOffset);
4955                info->mData->meta()->setInt32("rangeLength", rangeLength);
4956            } else {
4957                info->mData->setRange(rangeOffset, rangeLength);
4958            }
4959#if 0
4960            if (mCodec->mNativeWindow == NULL) {
4961                if (IsIDR(info->mData)) {
4962                    ALOGI("IDR frame");
4963                }
4964            }
4965#endif
4966
4967            if (mCodec->mSkipCutBuffer != NULL) {
4968                mCodec->mSkipCutBuffer->submit(info->mData);
4969            }
4970            info->mData->meta()->setInt64("timeUs", timeUs);
4971
4972            sp<AMessage> notify = mCodec->mNotify->dup();
4973            notify->setInt32("what", CodecBase::kWhatDrainThisBuffer);
4974            notify->setInt32("buffer-id", info->mBufferID);
4975            notify->setBuffer("buffer", info->mData);
4976            notify->setInt32("flags", flags);
4977
4978            reply->setInt32("buffer-id", info->mBufferID);
4979
4980            notify->setMessage("reply", reply);
4981
4982            notify->post();
4983
4984            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
4985
4986            if (flags & OMX_BUFFERFLAG_EOS) {
4987                ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
4988
4989                sp<AMessage> notify = mCodec->mNotify->dup();
4990                notify->setInt32("what", CodecBase::kWhatEOS);
4991                notify->setInt32("err", mCodec->mInputEOSResult);
4992                notify->post();
4993
4994                mCodec->mPortEOS[kPortIndexOutput] = true;
4995            }
4996            break;
4997        }
4998
4999        case FREE_BUFFERS:
5000            err = mCodec->freeBuffer(kPortIndexOutput, index);
5001            if (err != OK) {
5002                mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5003                return true;
5004            }
5005            break;
5006
5007        default:
5008            ALOGE("Invalid port mode: %d", mode);
5009            return false;
5010    }
5011
5012    return true;
5013}
5014
5015void ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
5016    IOMX::buffer_id bufferID;
5017    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
5018    ssize_t index;
5019    BufferInfo *info = mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
5020    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
5021    if (status != BufferInfo::OWNED_BY_DOWNSTREAM) {
5022        ALOGE("Wrong ownership in OBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
5023        mCodec->dumpBuffers(kPortIndexOutput);
5024        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
5025        return;
5026    }
5027
5028    android_native_rect_t crop;
5029    if (msg->findRect("crop", &crop.left, &crop.top, &crop.right, &crop.bottom)) {
5030        status_t err = native_window_set_crop(mCodec->mNativeWindow.get(), &crop);
5031        ALOGW_IF(err != NO_ERROR, "failed to set crop: %d", err);
5032    }
5033
5034    int32_t render;
5035    if (mCodec->mNativeWindow != NULL
5036            && msg->findInt32("render", &render) && render != 0
5037            && info->mData != NULL && info->mData->size() != 0) {
5038        ATRACE_NAME("render");
5039        // The client wants this buffer to be rendered.
5040
5041        int64_t timestampNs = 0;
5042        if (!msg->findInt64("timestampNs", &timestampNs)) {
5043            // TODO: it seems like we should use the timestamp
5044            // in the (media)buffer as it potentially came from
5045            // an input surface, but we did not propagate it prior to
5046            // API 20.  Perhaps check for target SDK version.
5047#if 0
5048            if (info->mData->meta()->findInt64("timeUs", &timestampNs)) {
5049                ALOGV("using buffer PTS of %" PRId64, timestampNs);
5050                timestampNs *= 1000;
5051            }
5052#endif
5053        }
5054
5055        status_t err;
5056        err = native_window_set_buffers_timestamp(mCodec->mNativeWindow.get(), timestampNs);
5057        ALOGW_IF(err != NO_ERROR, "failed to set buffer timestamp: %d", err);
5058
5059        info->checkReadFence("onOutputBufferDrained before queueBuffer");
5060        err = mCodec->mNativeWindow->queueBuffer(
5061                    mCodec->mNativeWindow.get(), info->mGraphicBuffer.get(), info->mFenceFd);
5062        info->mFenceFd = -1;
5063        if (err == OK) {
5064            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
5065        } else {
5066            mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5067            info->mStatus = BufferInfo::OWNED_BY_US;
5068            // keeping read fence as write fence to avoid clobbering
5069            info->mIsReadFence = false;
5070        }
5071    } else {
5072        if (mCodec->mNativeWindow != NULL &&
5073            (info->mData == NULL || info->mData->size() != 0)) {
5074            // move read fence into write fence to avoid clobbering
5075            info->mIsReadFence = false;
5076            ATRACE_NAME("frame-drop");
5077        }
5078        info->mStatus = BufferInfo::OWNED_BY_US;
5079    }
5080
5081    PortMode mode = getPortMode(kPortIndexOutput);
5082
5083    switch (mode) {
5084        case KEEP_BUFFERS:
5085        {
5086            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
5087
5088            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
5089                // We cannot resubmit the buffer we just rendered, dequeue
5090                // the spare instead.
5091
5092                info = mCodec->dequeueBufferFromNativeWindow();
5093            }
5094            break;
5095        }
5096
5097        case RESUBMIT_BUFFERS:
5098        {
5099            if (!mCodec->mPortEOS[kPortIndexOutput]) {
5100                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
5101                    // We cannot resubmit the buffer we just rendered, dequeue
5102                    // the spare instead.
5103
5104                    info = mCodec->dequeueBufferFromNativeWindow();
5105                }
5106
5107                if (info != NULL) {
5108                    ALOGV("[%s] calling fillBuffer %u",
5109                         mCodec->mComponentName.c_str(), info->mBufferID);
5110                    info->checkWriteFence("onOutputBufferDrained::RESUBMIT_BUFFERS");
5111                    status_t err = mCodec->mOMX->fillBuffer(
5112                            mCodec->mNode, info->mBufferID, info->mFenceFd);
5113                    info->mFenceFd = -1;
5114                    if (err == OK) {
5115                        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
5116                    } else {
5117                        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5118                    }
5119                }
5120            }
5121            break;
5122        }
5123
5124        case FREE_BUFFERS:
5125        {
5126            status_t err = mCodec->freeBuffer(kPortIndexOutput, index);
5127            if (err != OK) {
5128                mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5129            }
5130            break;
5131        }
5132
5133        default:
5134            ALOGE("Invalid port mode: %d", mode);
5135            return;
5136    }
5137}
5138
5139////////////////////////////////////////////////////////////////////////////////
5140
5141ACodec::UninitializedState::UninitializedState(ACodec *codec)
5142    : BaseState(codec) {
5143}
5144
5145void ACodec::UninitializedState::stateEntered() {
5146    ALOGV("Now uninitialized");
5147
5148    if (mDeathNotifier != NULL) {
5149        IInterface::asBinder(mCodec->mOMX)->unlinkToDeath(mDeathNotifier);
5150        mDeathNotifier.clear();
5151    }
5152
5153    mCodec->mNativeWindow.clear();
5154    mCodec->mNode = 0;
5155    mCodec->mOMX.clear();
5156    mCodec->mQuirks = 0;
5157    mCodec->mFlags = 0;
5158    mCodec->mInputMetadataType = kMetadataBufferTypeInvalid;
5159    mCodec->mOutputMetadataType = kMetadataBufferTypeInvalid;
5160    mCodec->mComponentName.clear();
5161}
5162
5163bool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
5164    bool handled = false;
5165
5166    switch (msg->what()) {
5167        case ACodec::kWhatSetup:
5168        {
5169            onSetup(msg);
5170
5171            handled = true;
5172            break;
5173        }
5174
5175        case ACodec::kWhatAllocateComponent:
5176        {
5177            onAllocateComponent(msg);
5178            handled = true;
5179            break;
5180        }
5181
5182        case ACodec::kWhatShutdown:
5183        {
5184            int32_t keepComponentAllocated;
5185            CHECK(msg->findInt32(
5186                        "keepComponentAllocated", &keepComponentAllocated));
5187            ALOGW_IF(keepComponentAllocated,
5188                     "cannot keep component allocated on shutdown in Uninitialized state");
5189
5190            sp<AMessage> notify = mCodec->mNotify->dup();
5191            notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
5192            notify->post();
5193
5194            handled = true;
5195            break;
5196        }
5197
5198        case ACodec::kWhatFlush:
5199        {
5200            sp<AMessage> notify = mCodec->mNotify->dup();
5201            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
5202            notify->post();
5203
5204            handled = true;
5205            break;
5206        }
5207
5208        case ACodec::kWhatReleaseCodecInstance:
5209        {
5210            // nothing to do, as we have already signaled shutdown
5211            handled = true;
5212            break;
5213        }
5214
5215        default:
5216            return BaseState::onMessageReceived(msg);
5217    }
5218
5219    return handled;
5220}
5221
5222void ACodec::UninitializedState::onSetup(
5223        const sp<AMessage> &msg) {
5224    if (onAllocateComponent(msg)
5225            && mCodec->mLoadedState->onConfigureComponent(msg)) {
5226        mCodec->mLoadedState->onStart();
5227    }
5228}
5229
5230bool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
5231    ALOGV("onAllocateComponent");
5232
5233    CHECK(mCodec->mNode == 0);
5234
5235    OMXClient client;
5236    if (client.connect() != OK) {
5237        mCodec->signalError(OMX_ErrorUndefined, NO_INIT);
5238        return false;
5239    }
5240
5241    sp<IOMX> omx = client.interface();
5242
5243    sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec);
5244
5245    mDeathNotifier = new DeathNotifier(notify);
5246    if (IInterface::asBinder(omx)->linkToDeath(mDeathNotifier) != OK) {
5247        // This was a local binder, if it dies so do we, we won't care
5248        // about any notifications in the afterlife.
5249        mDeathNotifier.clear();
5250    }
5251
5252    Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs;
5253
5254    AString mime;
5255
5256    AString componentName;
5257    uint32_t quirks = 0;
5258    int32_t encoder = false;
5259    if (msg->findString("componentName", &componentName)) {
5260        ssize_t index = matchingCodecs.add();
5261        OMXCodec::CodecNameAndQuirks *entry = &matchingCodecs.editItemAt(index);
5262        entry->mName = String8(componentName.c_str());
5263
5264        if (!OMXCodec::findCodecQuirks(
5265                    componentName.c_str(), &entry->mQuirks)) {
5266            entry->mQuirks = 0;
5267        }
5268    } else {
5269        CHECK(msg->findString("mime", &mime));
5270
5271        if (!msg->findInt32("encoder", &encoder)) {
5272            encoder = false;
5273        }
5274
5275        OMXCodec::findMatchingCodecs(
5276                mime.c_str(),
5277                encoder, // createEncoder
5278                NULL,  // matchComponentName
5279                0,     // flags
5280                &matchingCodecs);
5281    }
5282
5283    sp<CodecObserver> observer = new CodecObserver;
5284    IOMX::node_id node = 0;
5285
5286    status_t err = NAME_NOT_FOUND;
5287    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
5288            ++matchIndex) {
5289        componentName = matchingCodecs.itemAt(matchIndex).mName.string();
5290        quirks = matchingCodecs.itemAt(matchIndex).mQuirks;
5291
5292        pid_t tid = gettid();
5293        int prevPriority = androidGetThreadPriority(tid);
5294        androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
5295        err = omx->allocateNode(componentName.c_str(), observer, &node);
5296        androidSetThreadPriority(tid, prevPriority);
5297
5298        if (err == OK) {
5299            break;
5300        } else {
5301            ALOGW("Allocating component '%s' failed, try next one.", componentName.c_str());
5302        }
5303
5304        node = 0;
5305    }
5306
5307    if (node == 0) {
5308        if (!mime.empty()) {
5309            ALOGE("Unable to instantiate a %scoder for type '%s' with err %#x.",
5310                    encoder ? "en" : "de", mime.c_str(), err);
5311        } else {
5312            ALOGE("Unable to instantiate codec '%s' with err %#x.", componentName.c_str(), err);
5313        }
5314
5315        mCodec->signalError((OMX_ERRORTYPE)err, makeNoSideEffectStatus(err));
5316        return false;
5317    }
5318
5319    notify = new AMessage(kWhatOMXMessage, mCodec);
5320    observer->setNotificationMessage(notify);
5321
5322    mCodec->mComponentName = componentName;
5323    mCodec->mFlags = 0;
5324
5325    if (componentName.endsWith(".secure")) {
5326        mCodec->mFlags |= kFlagIsSecure;
5327        mCodec->mFlags |= kFlagIsGrallocUsageProtected;
5328        mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
5329    }
5330
5331    mCodec->mQuirks = quirks;
5332    mCodec->mOMX = omx;
5333    mCodec->mNode = node;
5334
5335    {
5336        sp<AMessage> notify = mCodec->mNotify->dup();
5337        notify->setInt32("what", CodecBase::kWhatComponentAllocated);
5338        notify->setString("componentName", mCodec->mComponentName.c_str());
5339        notify->post();
5340    }
5341
5342    mCodec->changeState(mCodec->mLoadedState);
5343
5344    return true;
5345}
5346
5347////////////////////////////////////////////////////////////////////////////////
5348
5349ACodec::LoadedState::LoadedState(ACodec *codec)
5350    : BaseState(codec) {
5351}
5352
5353void ACodec::LoadedState::stateEntered() {
5354    ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
5355
5356    mCodec->mPortEOS[kPortIndexInput] =
5357        mCodec->mPortEOS[kPortIndexOutput] = false;
5358
5359    mCodec->mInputEOSResult = OK;
5360
5361    mCodec->mDequeueCounter = 0;
5362    mCodec->mMetadataBuffersToSubmit = 0;
5363    mCodec->mRepeatFrameDelayUs = -1ll;
5364    mCodec->mInputFormat.clear();
5365    mCodec->mOutputFormat.clear();
5366    mCodec->mBaseOutputFormat.clear();
5367
5368    if (mCodec->mShutdownInProgress) {
5369        bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
5370
5371        mCodec->mShutdownInProgress = false;
5372        mCodec->mKeepComponentAllocated = false;
5373
5374        onShutdown(keepComponentAllocated);
5375    }
5376    mCodec->mExplicitShutdown = false;
5377
5378    mCodec->processDeferredMessages();
5379}
5380
5381void ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
5382    if (!keepComponentAllocated) {
5383        (void)mCodec->mOMX->freeNode(mCodec->mNode);
5384
5385        mCodec->changeState(mCodec->mUninitializedState);
5386    }
5387
5388    if (mCodec->mExplicitShutdown) {
5389        sp<AMessage> notify = mCodec->mNotify->dup();
5390        notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
5391        notify->post();
5392        mCodec->mExplicitShutdown = false;
5393    }
5394}
5395
5396bool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
5397    bool handled = false;
5398
5399    switch (msg->what()) {
5400        case ACodec::kWhatConfigureComponent:
5401        {
5402            onConfigureComponent(msg);
5403            handled = true;
5404            break;
5405        }
5406
5407        case ACodec::kWhatCreateInputSurface:
5408        {
5409            onCreateInputSurface(msg);
5410            handled = true;
5411            break;
5412        }
5413
5414        case ACodec::kWhatSetInputSurface:
5415        {
5416            onSetInputSurface(msg);
5417            handled = true;
5418            break;
5419        }
5420
5421        case ACodec::kWhatStart:
5422        {
5423            onStart();
5424            handled = true;
5425            break;
5426        }
5427
5428        case ACodec::kWhatShutdown:
5429        {
5430            int32_t keepComponentAllocated;
5431            CHECK(msg->findInt32(
5432                        "keepComponentAllocated", &keepComponentAllocated));
5433
5434            mCodec->mExplicitShutdown = true;
5435            onShutdown(keepComponentAllocated);
5436
5437            handled = true;
5438            break;
5439        }
5440
5441        case ACodec::kWhatFlush:
5442        {
5443            sp<AMessage> notify = mCodec->mNotify->dup();
5444            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
5445            notify->post();
5446
5447            handled = true;
5448            break;
5449        }
5450
5451        default:
5452            return BaseState::onMessageReceived(msg);
5453    }
5454
5455    return handled;
5456}
5457
5458bool ACodec::LoadedState::onConfigureComponent(
5459        const sp<AMessage> &msg) {
5460    ALOGV("onConfigureComponent");
5461
5462    CHECK(mCodec->mNode != 0);
5463
5464    status_t err = OK;
5465    AString mime;
5466    if (!msg->findString("mime", &mime)) {
5467        err = BAD_VALUE;
5468    } else {
5469        err = mCodec->configureCodec(mime.c_str(), msg);
5470    }
5471    if (err != OK) {
5472        ALOGE("[%s] configureCodec returning error %d",
5473              mCodec->mComponentName.c_str(), err);
5474
5475        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5476        return false;
5477    }
5478
5479    {
5480        sp<AMessage> notify = mCodec->mNotify->dup();
5481        notify->setInt32("what", CodecBase::kWhatComponentConfigured);
5482        notify->setMessage("input-format", mCodec->mInputFormat);
5483        notify->setMessage("output-format", mCodec->mOutputFormat);
5484        notify->post();
5485    }
5486
5487    return true;
5488}
5489
5490status_t ACodec::LoadedState::setupInputSurface() {
5491    status_t err = OK;
5492
5493    if (mCodec->mRepeatFrameDelayUs > 0ll) {
5494        err = mCodec->mOMX->setInternalOption(
5495                mCodec->mNode,
5496                kPortIndexInput,
5497                IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY,
5498                &mCodec->mRepeatFrameDelayUs,
5499                sizeof(mCodec->mRepeatFrameDelayUs));
5500
5501        if (err != OK) {
5502            ALOGE("[%s] Unable to configure option to repeat previous "
5503                  "frames (err %d)",
5504                  mCodec->mComponentName.c_str(),
5505                  err);
5506            return err;
5507        }
5508    }
5509
5510    if (mCodec->mMaxPtsGapUs > 0ll) {
5511        err = mCodec->mOMX->setInternalOption(
5512                mCodec->mNode,
5513                kPortIndexInput,
5514                IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP,
5515                &mCodec->mMaxPtsGapUs,
5516                sizeof(mCodec->mMaxPtsGapUs));
5517
5518        if (err != OK) {
5519            ALOGE("[%s] Unable to configure max timestamp gap (err %d)",
5520                    mCodec->mComponentName.c_str(),
5521                    err);
5522            return err;
5523        }
5524    }
5525
5526    if (mCodec->mMaxFps > 0) {
5527        err = mCodec->mOMX->setInternalOption(
5528                mCodec->mNode,
5529                kPortIndexInput,
5530                IOMX::INTERNAL_OPTION_MAX_FPS,
5531                &mCodec->mMaxFps,
5532                sizeof(mCodec->mMaxFps));
5533
5534        if (err != OK) {
5535            ALOGE("[%s] Unable to configure max fps (err %d)",
5536                    mCodec->mComponentName.c_str(),
5537                    err);
5538            return err;
5539        }
5540    }
5541
5542    if (mCodec->mTimePerCaptureUs > 0ll
5543            && mCodec->mTimePerFrameUs > 0ll) {
5544        int64_t timeLapse[2];
5545        timeLapse[0] = mCodec->mTimePerFrameUs;
5546        timeLapse[1] = mCodec->mTimePerCaptureUs;
5547        err = mCodec->mOMX->setInternalOption(
5548                mCodec->mNode,
5549                kPortIndexInput,
5550                IOMX::INTERNAL_OPTION_TIME_LAPSE,
5551                &timeLapse[0],
5552                sizeof(timeLapse));
5553
5554        if (err != OK) {
5555            ALOGE("[%s] Unable to configure time lapse (err %d)",
5556                    mCodec->mComponentName.c_str(),
5557                    err);
5558            return err;
5559        }
5560    }
5561
5562    if (mCodec->mCreateInputBuffersSuspended) {
5563        bool suspend = true;
5564        err = mCodec->mOMX->setInternalOption(
5565                mCodec->mNode,
5566                kPortIndexInput,
5567                IOMX::INTERNAL_OPTION_SUSPEND,
5568                &suspend,
5569                sizeof(suspend));
5570
5571        if (err != OK) {
5572            ALOGE("[%s] Unable to configure option to suspend (err %d)",
5573                  mCodec->mComponentName.c_str(),
5574                  err);
5575            return err;
5576        }
5577    }
5578
5579    return OK;
5580}
5581
5582void ACodec::LoadedState::onCreateInputSurface(
5583        const sp<AMessage> & /* msg */) {
5584    ALOGV("onCreateInputSurface");
5585
5586    sp<AMessage> notify = mCodec->mNotify->dup();
5587    notify->setInt32("what", CodecBase::kWhatInputSurfaceCreated);
5588
5589    sp<IGraphicBufferProducer> bufferProducer;
5590    status_t err = mCodec->mOMX->createInputSurface(
5591            mCodec->mNode, kPortIndexInput, &bufferProducer, &mCodec->mInputMetadataType);
5592
5593    if (err == OK) {
5594        err = setupInputSurface();
5595    }
5596
5597    if (err == OK) {
5598        notify->setObject("input-surface",
5599                new BufferProducerWrapper(bufferProducer));
5600    } else {
5601        // Can't use mCodec->signalError() here -- MediaCodec won't forward
5602        // the error through because it's in the "configured" state.  We
5603        // send a kWhatInputSurfaceCreated with an error value instead.
5604        ALOGE("[%s] onCreateInputSurface returning error %d",
5605                mCodec->mComponentName.c_str(), err);
5606        notify->setInt32("err", err);
5607    }
5608    notify->post();
5609}
5610
5611void ACodec::LoadedState::onSetInputSurface(
5612        const sp<AMessage> &msg) {
5613    ALOGV("onSetInputSurface");
5614
5615    sp<AMessage> notify = mCodec->mNotify->dup();
5616    notify->setInt32("what", CodecBase::kWhatInputSurfaceAccepted);
5617
5618    sp<RefBase> obj;
5619    CHECK(msg->findObject("input-surface", &obj));
5620    sp<PersistentSurface> surface = static_cast<PersistentSurface *>(obj.get());
5621
5622    status_t err = mCodec->mOMX->setInputSurface(
5623            mCodec->mNode, kPortIndexInput, surface->getBufferConsumer(),
5624            &mCodec->mInputMetadataType);
5625
5626    if (err == OK) {
5627        err = setupInputSurface();
5628    }
5629
5630    if (err != OK) {
5631        // Can't use mCodec->signalError() here -- MediaCodec won't forward
5632        // the error through because it's in the "configured" state.  We
5633        // send a kWhatInputSurfaceAccepted with an error value instead.
5634        ALOGE("[%s] onSetInputSurface returning error %d",
5635                mCodec->mComponentName.c_str(), err);
5636        notify->setInt32("err", err);
5637    }
5638    notify->post();
5639}
5640
5641void ACodec::LoadedState::onStart() {
5642    ALOGV("onStart");
5643
5644    status_t err = mCodec->mOMX->sendCommand(mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle);
5645    if (err != OK) {
5646        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5647    } else {
5648        mCodec->changeState(mCodec->mLoadedToIdleState);
5649    }
5650}
5651
5652////////////////////////////////////////////////////////////////////////////////
5653
5654ACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
5655    : BaseState(codec) {
5656}
5657
5658void ACodec::LoadedToIdleState::stateEntered() {
5659    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
5660
5661    status_t err;
5662    if ((err = allocateBuffers()) != OK) {
5663        ALOGE("Failed to allocate buffers after transitioning to IDLE state "
5664             "(error 0x%08x)",
5665             err);
5666
5667        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5668
5669        mCodec->changeState(mCodec->mLoadedState);
5670    }
5671}
5672
5673status_t ACodec::LoadedToIdleState::allocateBuffers() {
5674    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
5675
5676    if (err != OK) {
5677        return err;
5678    }
5679
5680    return mCodec->allocateBuffersOnPort(kPortIndexOutput);
5681}
5682
5683bool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
5684    switch (msg->what()) {
5685        case kWhatSetParameters:
5686        case kWhatShutdown:
5687        {
5688            mCodec->deferMessage(msg);
5689            return true;
5690        }
5691
5692        case kWhatSignalEndOfInputStream:
5693        {
5694            mCodec->onSignalEndOfInputStream();
5695            return true;
5696        }
5697
5698        case kWhatResume:
5699        {
5700            // We'll be active soon enough.
5701            return true;
5702        }
5703
5704        case kWhatFlush:
5705        {
5706            // We haven't even started yet, so we're flushed alright...
5707            sp<AMessage> notify = mCodec->mNotify->dup();
5708            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
5709            notify->post();
5710            return true;
5711        }
5712
5713        default:
5714            return BaseState::onMessageReceived(msg);
5715    }
5716}
5717
5718bool ACodec::LoadedToIdleState::onOMXEvent(
5719        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5720    switch (event) {
5721        case OMX_EventCmdComplete:
5722        {
5723            status_t err = OK;
5724            if (data1 != (OMX_U32)OMX_CommandStateSet
5725                    || data2 != (OMX_U32)OMX_StateIdle) {
5726                ALOGE("Unexpected command completion in LoadedToIdleState: %s(%u) %s(%u)",
5727                        asString((OMX_COMMANDTYPE)data1), data1,
5728                        asString((OMX_STATETYPE)data2), data2);
5729                err = FAILED_TRANSACTION;
5730            }
5731
5732            if (err == OK) {
5733                err = mCodec->mOMX->sendCommand(
5734                    mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting);
5735            }
5736
5737            if (err != OK) {
5738                mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5739            } else {
5740                mCodec->changeState(mCodec->mIdleToExecutingState);
5741            }
5742
5743            return true;
5744        }
5745
5746        default:
5747            return BaseState::onOMXEvent(event, data1, data2);
5748    }
5749}
5750
5751////////////////////////////////////////////////////////////////////////////////
5752
5753ACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
5754    : BaseState(codec) {
5755}
5756
5757void ACodec::IdleToExecutingState::stateEntered() {
5758    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
5759}
5760
5761bool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
5762    switch (msg->what()) {
5763        case kWhatSetParameters:
5764        case kWhatShutdown:
5765        {
5766            mCodec->deferMessage(msg);
5767            return true;
5768        }
5769
5770        case kWhatResume:
5771        {
5772            // We'll be active soon enough.
5773            return true;
5774        }
5775
5776        case kWhatFlush:
5777        {
5778            // We haven't even started yet, so we're flushed alright...
5779            sp<AMessage> notify = mCodec->mNotify->dup();
5780            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
5781            notify->post();
5782
5783            return true;
5784        }
5785
5786        case kWhatSignalEndOfInputStream:
5787        {
5788            mCodec->onSignalEndOfInputStream();
5789            return true;
5790        }
5791
5792        default:
5793            return BaseState::onMessageReceived(msg);
5794    }
5795}
5796
5797bool ACodec::IdleToExecutingState::onOMXEvent(
5798        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5799    switch (event) {
5800        case OMX_EventCmdComplete:
5801        {
5802            if (data1 != (OMX_U32)OMX_CommandStateSet
5803                    || data2 != (OMX_U32)OMX_StateExecuting) {
5804                ALOGE("Unexpected command completion in IdleToExecutingState: %s(%u) %s(%u)",
5805                        asString((OMX_COMMANDTYPE)data1), data1,
5806                        asString((OMX_STATETYPE)data2), data2);
5807                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
5808                return true;
5809            }
5810
5811            mCodec->mExecutingState->resume();
5812            mCodec->changeState(mCodec->mExecutingState);
5813
5814            return true;
5815        }
5816
5817        default:
5818            return BaseState::onOMXEvent(event, data1, data2);
5819    }
5820}
5821
5822////////////////////////////////////////////////////////////////////////////////
5823
5824ACodec::ExecutingState::ExecutingState(ACodec *codec)
5825    : BaseState(codec),
5826      mActive(false) {
5827}
5828
5829ACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
5830        OMX_U32 /* portIndex */) {
5831    return RESUBMIT_BUFFERS;
5832}
5833
5834void ACodec::ExecutingState::submitOutputMetaBuffers() {
5835    // submit as many buffers as there are input buffers with the codec
5836    // in case we are in port reconfiguring
5837    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
5838        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
5839
5840        if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) {
5841            if (mCodec->submitOutputMetadataBuffer() != OK)
5842                break;
5843        }
5844    }
5845
5846    // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
5847    mCodec->signalSubmitOutputMetadataBufferIfEOS_workaround();
5848}
5849
5850void ACodec::ExecutingState::submitRegularOutputBuffers() {
5851    bool failed = false;
5852    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
5853        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
5854
5855        if (mCodec->mNativeWindow != NULL) {
5856            if (info->mStatus != BufferInfo::OWNED_BY_US
5857                    && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
5858                ALOGE("buffers should be owned by us or the surface");
5859                failed = true;
5860                break;
5861            }
5862
5863            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
5864                continue;
5865            }
5866        } else {
5867            if (info->mStatus != BufferInfo::OWNED_BY_US) {
5868                ALOGE("buffers should be owned by us");
5869                failed = true;
5870                break;
5871            }
5872        }
5873
5874        ALOGV("[%s] calling fillBuffer %u", mCodec->mComponentName.c_str(), info->mBufferID);
5875
5876        info->checkWriteFence("submitRegularOutputBuffers");
5877        status_t err = mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID, info->mFenceFd);
5878        info->mFenceFd = -1;
5879        if (err != OK) {
5880            failed = true;
5881            break;
5882        }
5883
5884        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
5885    }
5886
5887    if (failed) {
5888        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
5889    }
5890}
5891
5892void ACodec::ExecutingState::submitOutputBuffers() {
5893    submitRegularOutputBuffers();
5894    if (mCodec->storingMetadataInDecodedBuffers()) {
5895        submitOutputMetaBuffers();
5896    }
5897}
5898
5899void ACodec::ExecutingState::resume() {
5900    if (mActive) {
5901        ALOGV("[%s] We're already active, no need to resume.", mCodec->mComponentName.c_str());
5902        return;
5903    }
5904
5905    submitOutputBuffers();
5906
5907    // Post all available input buffers
5908    if (mCodec->mBuffers[kPortIndexInput].size() == 0u) {
5909        ALOGW("[%s] we don't have any input buffers to resume", mCodec->mComponentName.c_str());
5910    }
5911
5912    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); i++) {
5913        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
5914        if (info->mStatus == BufferInfo::OWNED_BY_US) {
5915            postFillThisBuffer(info);
5916        }
5917    }
5918
5919    mActive = true;
5920}
5921
5922void ACodec::ExecutingState::stateEntered() {
5923    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
5924
5925    mCodec->processDeferredMessages();
5926}
5927
5928bool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
5929    bool handled = false;
5930
5931    switch (msg->what()) {
5932        case kWhatShutdown:
5933        {
5934            int32_t keepComponentAllocated;
5935            CHECK(msg->findInt32(
5936                        "keepComponentAllocated", &keepComponentAllocated));
5937
5938            mCodec->mShutdownInProgress = true;
5939            mCodec->mExplicitShutdown = true;
5940            mCodec->mKeepComponentAllocated = keepComponentAllocated;
5941
5942            mActive = false;
5943
5944            status_t err = mCodec->mOMX->sendCommand(
5945                    mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle);
5946            if (err != OK) {
5947                if (keepComponentAllocated) {
5948                    mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
5949                }
5950                // TODO: do some recovery here.
5951            } else {
5952                mCodec->changeState(mCodec->mExecutingToIdleState);
5953            }
5954
5955            handled = true;
5956            break;
5957        }
5958
5959        case kWhatFlush:
5960        {
5961            ALOGV("[%s] ExecutingState flushing now "
5962                 "(codec owns %zu/%zu input, %zu/%zu output).",
5963                    mCodec->mComponentName.c_str(),
5964                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
5965                    mCodec->mBuffers[kPortIndexInput].size(),
5966                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
5967                    mCodec->mBuffers[kPortIndexOutput].size());
5968
5969            mActive = false;
5970
5971            status_t err = mCodec->mOMX->sendCommand(mCodec->mNode, OMX_CommandFlush, OMX_ALL);
5972            if (err != OK) {
5973                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
5974            } else {
5975                mCodec->changeState(mCodec->mFlushingState);
5976            }
5977
5978            handled = true;
5979            break;
5980        }
5981
5982        case kWhatResume:
5983        {
5984            resume();
5985
5986            handled = true;
5987            break;
5988        }
5989
5990        case kWhatRequestIDRFrame:
5991        {
5992            status_t err = mCodec->requestIDRFrame();
5993            if (err != OK) {
5994                ALOGW("Requesting an IDR frame failed.");
5995            }
5996
5997            handled = true;
5998            break;
5999        }
6000
6001        case kWhatSetParameters:
6002        {
6003            sp<AMessage> params;
6004            CHECK(msg->findMessage("params", &params));
6005
6006            status_t err = mCodec->setParameters(params);
6007
6008            sp<AMessage> reply;
6009            if (msg->findMessage("reply", &reply)) {
6010                reply->setInt32("err", err);
6011                reply->post();
6012            }
6013
6014            handled = true;
6015            break;
6016        }
6017
6018        case ACodec::kWhatSignalEndOfInputStream:
6019        {
6020            mCodec->onSignalEndOfInputStream();
6021            handled = true;
6022            break;
6023        }
6024
6025        // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
6026        case kWhatSubmitOutputMetadataBufferIfEOS:
6027        {
6028            if (mCodec->mPortEOS[kPortIndexInput] &&
6029                    !mCodec->mPortEOS[kPortIndexOutput]) {
6030                status_t err = mCodec->submitOutputMetadataBuffer();
6031                if (err == OK) {
6032                    mCodec->signalSubmitOutputMetadataBufferIfEOS_workaround();
6033                }
6034            }
6035            return true;
6036        }
6037
6038        default:
6039            handled = BaseState::onMessageReceived(msg);
6040            break;
6041    }
6042
6043    return handled;
6044}
6045
6046status_t ACodec::setParameters(const sp<AMessage> &params) {
6047    int32_t videoBitrate;
6048    if (params->findInt32("video-bitrate", &videoBitrate)) {
6049        OMX_VIDEO_CONFIG_BITRATETYPE configParams;
6050        InitOMXParams(&configParams);
6051        configParams.nPortIndex = kPortIndexOutput;
6052        configParams.nEncodeBitrate = videoBitrate;
6053
6054        status_t err = mOMX->setConfig(
6055                mNode,
6056                OMX_IndexConfigVideoBitrate,
6057                &configParams,
6058                sizeof(configParams));
6059
6060        if (err != OK) {
6061            ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
6062                   videoBitrate, err);
6063
6064            return err;
6065        }
6066    }
6067
6068    int64_t skipFramesBeforeUs;
6069    if (params->findInt64("skip-frames-before", &skipFramesBeforeUs)) {
6070        status_t err =
6071            mOMX->setInternalOption(
6072                     mNode,
6073                     kPortIndexInput,
6074                     IOMX::INTERNAL_OPTION_START_TIME,
6075                     &skipFramesBeforeUs,
6076                     sizeof(skipFramesBeforeUs));
6077
6078        if (err != OK) {
6079            ALOGE("Failed to set parameter 'skip-frames-before' (err %d)", err);
6080            return err;
6081        }
6082    }
6083
6084    int32_t dropInputFrames;
6085    if (params->findInt32("drop-input-frames", &dropInputFrames)) {
6086        bool suspend = dropInputFrames != 0;
6087
6088        status_t err =
6089            mOMX->setInternalOption(
6090                     mNode,
6091                     kPortIndexInput,
6092                     IOMX::INTERNAL_OPTION_SUSPEND,
6093                     &suspend,
6094                     sizeof(suspend));
6095
6096        if (err != OK) {
6097            ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err);
6098            return err;
6099        }
6100    }
6101
6102    int32_t dummy;
6103    if (params->findInt32("request-sync", &dummy)) {
6104        status_t err = requestIDRFrame();
6105
6106        if (err != OK) {
6107            ALOGE("Requesting a sync frame failed w/ err %d", err);
6108            return err;
6109        }
6110    }
6111
6112    float rate;
6113    if (params->findFloat("operating-rate", &rate) && rate > 0) {
6114        status_t err = setOperatingRate(rate, mIsVideo);
6115        if (err != OK) {
6116            ALOGE("Failed to set parameter 'operating-rate' (err %d)", err);
6117            return err;
6118        }
6119    }
6120
6121    return OK;
6122}
6123
6124void ACodec::onSignalEndOfInputStream() {
6125    sp<AMessage> notify = mNotify->dup();
6126    notify->setInt32("what", CodecBase::kWhatSignaledInputEOS);
6127
6128    status_t err = mOMX->signalEndOfInputStream(mNode);
6129    if (err != OK) {
6130        notify->setInt32("err", err);
6131    }
6132    notify->post();
6133}
6134
6135bool ACodec::ExecutingState::onOMXEvent(
6136        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6137    switch (event) {
6138        case OMX_EventPortSettingsChanged:
6139        {
6140            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
6141
6142            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
6143                mCodec->mMetadataBuffersToSubmit = 0;
6144                CHECK_EQ(mCodec->mOMX->sendCommand(
6145                            mCodec->mNode,
6146                            OMX_CommandPortDisable, kPortIndexOutput),
6147                         (status_t)OK);
6148
6149                mCodec->freeOutputBuffersNotOwnedByComponent();
6150
6151                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
6152            } else if (data2 == OMX_IndexConfigCommonOutputCrop) {
6153                mCodec->mSentFormat = false;
6154            } else {
6155                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08x",
6156                     mCodec->mComponentName.c_str(), data2);
6157            }
6158
6159            return true;
6160        }
6161
6162        case OMX_EventBufferFlag:
6163        {
6164            return true;
6165        }
6166
6167        default:
6168            return BaseState::onOMXEvent(event, data1, data2);
6169    }
6170}
6171
6172////////////////////////////////////////////////////////////////////////////////
6173
6174ACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
6175        ACodec *codec)
6176    : BaseState(codec) {
6177}
6178
6179ACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
6180        OMX_U32 portIndex) {
6181    if (portIndex == kPortIndexOutput) {
6182        return FREE_BUFFERS;
6183    }
6184
6185    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
6186
6187    return RESUBMIT_BUFFERS;
6188}
6189
6190bool ACodec::OutputPortSettingsChangedState::onMessageReceived(
6191        const sp<AMessage> &msg) {
6192    bool handled = false;
6193
6194    switch (msg->what()) {
6195        case kWhatFlush:
6196        case kWhatShutdown:
6197        case kWhatResume:
6198        case kWhatSetParameters:
6199        {
6200            if (msg->what() == kWhatResume) {
6201                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
6202            }
6203
6204            mCodec->deferMessage(msg);
6205            handled = true;
6206            break;
6207        }
6208
6209        default:
6210            handled = BaseState::onMessageReceived(msg);
6211            break;
6212    }
6213
6214    return handled;
6215}
6216
6217void ACodec::OutputPortSettingsChangedState::stateEntered() {
6218    ALOGV("[%s] Now handling output port settings change",
6219         mCodec->mComponentName.c_str());
6220}
6221
6222bool ACodec::OutputPortSettingsChangedState::onOMXEvent(
6223        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6224    switch (event) {
6225        case OMX_EventCmdComplete:
6226        {
6227            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
6228                if (data2 != (OMX_U32)kPortIndexOutput) {
6229                    ALOGW("ignoring EventCmdComplete CommandPortDisable for port %u", data2);
6230                    return false;
6231                }
6232
6233                ALOGV("[%s] Output port now disabled.", mCodec->mComponentName.c_str());
6234
6235                status_t err = OK;
6236                if (!mCodec->mBuffers[kPortIndexOutput].isEmpty()) {
6237                    ALOGE("disabled port should be empty, but has %zu buffers",
6238                            mCodec->mBuffers[kPortIndexOutput].size());
6239                    err = FAILED_TRANSACTION;
6240                } else {
6241                    mCodec->mDealer[kPortIndexOutput].clear();
6242                }
6243
6244                if (err == OK) {
6245                    err = mCodec->mOMX->sendCommand(
6246                            mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput);
6247                }
6248
6249                if (err == OK) {
6250                    err = mCodec->allocateBuffersOnPort(kPortIndexOutput);
6251                    ALOGE_IF(err != OK, "Failed to allocate output port buffers after port "
6252                            "reconfiguration: (%d)", err);
6253                }
6254
6255                if (err != OK) {
6256                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
6257
6258                    // This is technically not correct, but appears to be
6259                    // the only way to free the component instance.
6260                    // Controlled transitioning from excecuting->idle
6261                    // and idle->loaded seem impossible probably because
6262                    // the output port never finishes re-enabling.
6263                    mCodec->mShutdownInProgress = true;
6264                    mCodec->mKeepComponentAllocated = false;
6265                    mCodec->changeState(mCodec->mLoadedState);
6266                }
6267
6268                return true;
6269            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
6270                if (data2 != (OMX_U32)kPortIndexOutput) {
6271                    ALOGW("ignoring EventCmdComplete OMX_CommandPortEnable for port %u", data2);
6272                    return false;
6273                }
6274
6275                mCodec->mSentFormat = false;
6276
6277                ALOGV("[%s] Output port now reenabled.", mCodec->mComponentName.c_str());
6278
6279                if (mCodec->mExecutingState->active()) {
6280                    mCodec->mExecutingState->submitOutputBuffers();
6281                }
6282
6283                mCodec->changeState(mCodec->mExecutingState);
6284
6285                return true;
6286            }
6287
6288            return false;
6289        }
6290
6291        default:
6292            return false;
6293    }
6294}
6295
6296////////////////////////////////////////////////////////////////////////////////
6297
6298ACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
6299    : BaseState(codec),
6300      mComponentNowIdle(false) {
6301}
6302
6303bool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
6304    bool handled = false;
6305
6306    switch (msg->what()) {
6307        case kWhatFlush:
6308        {
6309            // Don't send me a flush request if you previously wanted me
6310            // to shutdown.
6311            ALOGW("Ignoring flush request in ExecutingToIdleState");
6312            break;
6313        }
6314
6315        case kWhatShutdown:
6316        {
6317            // We're already doing that...
6318
6319            handled = true;
6320            break;
6321        }
6322
6323        default:
6324            handled = BaseState::onMessageReceived(msg);
6325            break;
6326    }
6327
6328    return handled;
6329}
6330
6331void ACodec::ExecutingToIdleState::stateEntered() {
6332    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
6333
6334    mComponentNowIdle = false;
6335    mCodec->mSentFormat = false;
6336}
6337
6338bool ACodec::ExecutingToIdleState::onOMXEvent(
6339        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6340    switch (event) {
6341        case OMX_EventCmdComplete:
6342        {
6343            if (data1 != (OMX_U32)OMX_CommandStateSet
6344                    || data2 != (OMX_U32)OMX_StateIdle) {
6345                ALOGE("Unexpected command completion in ExecutingToIdleState: %s(%u) %s(%u)",
6346                        asString((OMX_COMMANDTYPE)data1), data1,
6347                        asString((OMX_STATETYPE)data2), data2);
6348                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
6349                return true;
6350            }
6351
6352            mComponentNowIdle = true;
6353
6354            changeStateIfWeOwnAllBuffers();
6355
6356            return true;
6357        }
6358
6359        case OMX_EventPortSettingsChanged:
6360        case OMX_EventBufferFlag:
6361        {
6362            // We're shutting down and don't care about this anymore.
6363            return true;
6364        }
6365
6366        default:
6367            return BaseState::onOMXEvent(event, data1, data2);
6368    }
6369}
6370
6371void ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
6372    if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
6373        status_t err = mCodec->mOMX->sendCommand(
6374                mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded);
6375        if (err == OK) {
6376            err = mCodec->freeBuffersOnPort(kPortIndexInput);
6377            status_t err2 = mCodec->freeBuffersOnPort(kPortIndexOutput);
6378            if (err == OK) {
6379                err = err2;
6380            }
6381        }
6382
6383        if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown)
6384                && mCodec->mNativeWindow != NULL) {
6385            // We push enough 1x1 blank buffers to ensure that one of
6386            // them has made it to the display.  This allows the OMX
6387            // component teardown to zero out any protected buffers
6388            // without the risk of scanning out one of those buffers.
6389            pushBlankBuffersToNativeWindow(mCodec->mNativeWindow.get());
6390        }
6391
6392        if (err != OK) {
6393            mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
6394            return;
6395        }
6396
6397        mCodec->changeState(mCodec->mIdleToLoadedState);
6398    }
6399}
6400
6401void ACodec::ExecutingToIdleState::onInputBufferFilled(
6402        const sp<AMessage> &msg) {
6403    BaseState::onInputBufferFilled(msg);
6404
6405    changeStateIfWeOwnAllBuffers();
6406}
6407
6408void ACodec::ExecutingToIdleState::onOutputBufferDrained(
6409        const sp<AMessage> &msg) {
6410    BaseState::onOutputBufferDrained(msg);
6411
6412    changeStateIfWeOwnAllBuffers();
6413}
6414
6415////////////////////////////////////////////////////////////////////////////////
6416
6417ACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
6418    : BaseState(codec) {
6419}
6420
6421bool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
6422    bool handled = false;
6423
6424    switch (msg->what()) {
6425        case kWhatShutdown:
6426        {
6427            // We're already doing that...
6428
6429            handled = true;
6430            break;
6431        }
6432
6433        case kWhatFlush:
6434        {
6435            // Don't send me a flush request if you previously wanted me
6436            // to shutdown.
6437            ALOGE("Got flush request in IdleToLoadedState");
6438            break;
6439        }
6440
6441        default:
6442            handled = BaseState::onMessageReceived(msg);
6443            break;
6444    }
6445
6446    return handled;
6447}
6448
6449void ACodec::IdleToLoadedState::stateEntered() {
6450    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
6451}
6452
6453bool ACodec::IdleToLoadedState::onOMXEvent(
6454        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6455    switch (event) {
6456        case OMX_EventCmdComplete:
6457        {
6458            if (data1 != (OMX_U32)OMX_CommandStateSet
6459                    || data2 != (OMX_U32)OMX_StateLoaded) {
6460                ALOGE("Unexpected command completion in IdleToLoadedState: %s(%u) %s(%u)",
6461                        asString((OMX_COMMANDTYPE)data1), data1,
6462                        asString((OMX_STATETYPE)data2), data2);
6463                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
6464                return true;
6465            }
6466
6467            mCodec->changeState(mCodec->mLoadedState);
6468
6469            return true;
6470        }
6471
6472        default:
6473            return BaseState::onOMXEvent(event, data1, data2);
6474    }
6475}
6476
6477////////////////////////////////////////////////////////////////////////////////
6478
6479ACodec::FlushingState::FlushingState(ACodec *codec)
6480    : BaseState(codec) {
6481}
6482
6483void ACodec::FlushingState::stateEntered() {
6484    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
6485
6486    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
6487}
6488
6489bool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
6490    bool handled = false;
6491
6492    switch (msg->what()) {
6493        case kWhatShutdown:
6494        {
6495            mCodec->deferMessage(msg);
6496            break;
6497        }
6498
6499        case kWhatFlush:
6500        {
6501            // We're already doing this right now.
6502            handled = true;
6503            break;
6504        }
6505
6506        default:
6507            handled = BaseState::onMessageReceived(msg);
6508            break;
6509    }
6510
6511    return handled;
6512}
6513
6514bool ACodec::FlushingState::onOMXEvent(
6515        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6516    ALOGV("[%s] FlushingState onOMXEvent(%u,%d)",
6517            mCodec->mComponentName.c_str(), event, (OMX_S32)data1);
6518
6519    switch (event) {
6520        case OMX_EventCmdComplete:
6521        {
6522            if (data1 != (OMX_U32)OMX_CommandFlush) {
6523                ALOGE("unexpected EventCmdComplete %s(%d) data2:%d in FlushingState",
6524                        asString((OMX_COMMANDTYPE)data1), data1, data2);
6525                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
6526                return true;
6527            }
6528
6529            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
6530                if (mFlushComplete[data2]) {
6531                    ALOGW("Flush already completed for %s port",
6532                            data2 == kPortIndexInput ? "input" : "output");
6533                    return true;
6534                }
6535                mFlushComplete[data2] = true;
6536
6537                if (mFlushComplete[kPortIndexInput] && mFlushComplete[kPortIndexOutput]) {
6538                    changeStateIfWeOwnAllBuffers();
6539                }
6540            } else if (data2 == OMX_ALL) {
6541                if (!mFlushComplete[kPortIndexInput] || !mFlushComplete[kPortIndexOutput]) {
6542                    ALOGW("received flush complete event for OMX_ALL before ports have been"
6543                            "flushed (%d/%d)",
6544                            mFlushComplete[kPortIndexInput], mFlushComplete[kPortIndexOutput]);
6545                    return false;
6546                }
6547
6548                changeStateIfWeOwnAllBuffers();
6549            } else {
6550                ALOGW("data2 not OMX_ALL but %u in EventCmdComplete CommandFlush", data2);
6551            }
6552
6553            return true;
6554        }
6555
6556        case OMX_EventPortSettingsChanged:
6557        {
6558            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec);
6559            msg->setInt32("type", omx_message::EVENT);
6560            msg->setInt32("node", mCodec->mNode);
6561            msg->setInt32("event", event);
6562            msg->setInt32("data1", data1);
6563            msg->setInt32("data2", data2);
6564
6565            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
6566                 mCodec->mComponentName.c_str());
6567
6568            mCodec->deferMessage(msg);
6569
6570            return true;
6571        }
6572
6573        default:
6574            return BaseState::onOMXEvent(event, data1, data2);
6575    }
6576
6577    return true;
6578}
6579
6580void ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
6581    BaseState::onOutputBufferDrained(msg);
6582
6583    changeStateIfWeOwnAllBuffers();
6584}
6585
6586void ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
6587    BaseState::onInputBufferFilled(msg);
6588
6589    changeStateIfWeOwnAllBuffers();
6590}
6591
6592void ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
6593    if (mFlushComplete[kPortIndexInput]
6594            && mFlushComplete[kPortIndexOutput]
6595            && mCodec->allYourBuffersAreBelongToUs()) {
6596        // We now own all buffers except possibly those still queued with
6597        // the native window for rendering. Let's get those back as well.
6598        mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
6599
6600        sp<AMessage> notify = mCodec->mNotify->dup();
6601        notify->setInt32("what", CodecBase::kWhatFlushCompleted);
6602        notify->post();
6603
6604        mCodec->mPortEOS[kPortIndexInput] =
6605            mCodec->mPortEOS[kPortIndexOutput] = false;
6606
6607        mCodec->mInputEOSResult = OK;
6608
6609        if (mCodec->mSkipCutBuffer != NULL) {
6610            mCodec->mSkipCutBuffer->clear();
6611        }
6612
6613        mCodec->changeState(mCodec->mExecutingState);
6614    }
6615}
6616
6617}  // namespace android
6618