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