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