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