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