ACodec.cpp revision b1cf03160fa7e7bc6e5cf138db07a7e1ab2ecb26
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        if (mSkipCutBuffer != NULL) {
4442            size_t prevbufsize = mSkipCutBuffer->size();
4443            if (prevbufsize != 0) {
4444                ALOGW("Replacing SkipCutBuffer holding %zu bytes", prevbufsize);
4445            }
4446        }
4447        mSkipCutBuffer = new SkipCutBuffer(mEncoderDelay, mEncoderPadding, channelCount);
4448    }
4449
4450    notify->post();
4451
4452    mSentFormat = true;
4453}
4454
4455void ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
4456    sp<AMessage> notify = mNotify->dup();
4457    notify->setInt32("what", CodecBase::kWhatError);
4458    ALOGE("signalError(omxError %#x, internalError %d)", error, internalError);
4459
4460    if (internalError == UNKNOWN_ERROR) { // find better error code
4461        const status_t omxStatus = statusFromOMXError(error);
4462        if (omxStatus != 0) {
4463            internalError = omxStatus;
4464        } else {
4465            ALOGW("Invalid OMX error %#x", error);
4466        }
4467    }
4468
4469    mFatalError = true;
4470
4471    notify->setInt32("err", internalError);
4472    notify->setInt32("actionCode", ACTION_CODE_FATAL); // could translate from OMX error.
4473    notify->post();
4474}
4475
4476////////////////////////////////////////////////////////////////////////////////
4477
4478ACodec::PortDescription::PortDescription() {
4479}
4480
4481status_t ACodec::requestIDRFrame() {
4482    if (!mIsEncoder) {
4483        return ERROR_UNSUPPORTED;
4484    }
4485
4486    OMX_CONFIG_INTRAREFRESHVOPTYPE params;
4487    InitOMXParams(&params);
4488
4489    params.nPortIndex = kPortIndexOutput;
4490    params.IntraRefreshVOP = OMX_TRUE;
4491
4492    return mOMX->setConfig(
4493            mNode,
4494            OMX_IndexConfigVideoIntraVOPRefresh,
4495            &params,
4496            sizeof(params));
4497}
4498
4499void ACodec::PortDescription::addBuffer(
4500        IOMX::buffer_id id, const sp<ABuffer> &buffer) {
4501    mBufferIDs.push_back(id);
4502    mBuffers.push_back(buffer);
4503}
4504
4505size_t ACodec::PortDescription::countBuffers() {
4506    return mBufferIDs.size();
4507}
4508
4509IOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const {
4510    return mBufferIDs.itemAt(index);
4511}
4512
4513sp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const {
4514    return mBuffers.itemAt(index);
4515}
4516
4517////////////////////////////////////////////////////////////////////////////////
4518
4519ACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
4520    : AState(parentState),
4521      mCodec(codec) {
4522}
4523
4524ACodec::BaseState::PortMode ACodec::BaseState::getPortMode(
4525        OMX_U32 /* portIndex */) {
4526    return KEEP_BUFFERS;
4527}
4528
4529bool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
4530    switch (msg->what()) {
4531        case kWhatInputBufferFilled:
4532        {
4533            onInputBufferFilled(msg);
4534            break;
4535        }
4536
4537        case kWhatOutputBufferDrained:
4538        {
4539            onOutputBufferDrained(msg);
4540            break;
4541        }
4542
4543        case ACodec::kWhatOMXMessageList:
4544        {
4545            return checkOMXMessage(msg) ? onOMXMessageList(msg) : true;
4546        }
4547
4548        case ACodec::kWhatOMXMessageItem:
4549        {
4550            // no need to check as we already did it for kWhatOMXMessageList
4551            return onOMXMessage(msg);
4552        }
4553
4554        case ACodec::kWhatOMXMessage:
4555        {
4556            return checkOMXMessage(msg) ? onOMXMessage(msg) : true;
4557        }
4558
4559        case ACodec::kWhatSetSurface:
4560        {
4561            sp<AReplyToken> replyID;
4562            CHECK(msg->senderAwaitsResponse(&replyID));
4563
4564            sp<RefBase> obj;
4565            CHECK(msg->findObject("surface", &obj));
4566
4567            status_t err = mCodec->handleSetSurface(static_cast<Surface *>(obj.get()));
4568
4569            sp<AMessage> response = new AMessage;
4570            response->setInt32("err", err);
4571            response->postReply(replyID);
4572            break;
4573        }
4574
4575        case ACodec::kWhatCreateInputSurface:
4576        case ACodec::kWhatSetInputSurface:
4577        case ACodec::kWhatSignalEndOfInputStream:
4578        {
4579            // This may result in an app illegal state exception.
4580            ALOGE("Message 0x%x was not handled", msg->what());
4581            mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
4582            return true;
4583        }
4584
4585        case ACodec::kWhatOMXDied:
4586        {
4587            // This will result in kFlagSawMediaServerDie handling in MediaCodec.
4588            ALOGE("OMX/mediaserver died, signalling error!");
4589            mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT);
4590            break;
4591        }
4592
4593        case ACodec::kWhatReleaseCodecInstance:
4594        {
4595            ALOGI("[%s] forcing the release of codec",
4596                    mCodec->mComponentName.c_str());
4597            status_t err = mCodec->mOMX->freeNode(mCodec->mNode);
4598            ALOGE_IF("[%s] failed to release codec instance: err=%d",
4599                       mCodec->mComponentName.c_str(), err);
4600            sp<AMessage> notify = mCodec->mNotify->dup();
4601            notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
4602            notify->post();
4603            break;
4604        }
4605
4606        default:
4607            return false;
4608    }
4609
4610    return true;
4611}
4612
4613bool ACodec::BaseState::checkOMXMessage(const sp<AMessage> &msg) {
4614    // there is a possibility that this is an outstanding message for a
4615    // codec that we have already destroyed
4616    if (mCodec->mNode == 0) {
4617        ALOGI("ignoring message as already freed component: %s",
4618                msg->debugString().c_str());
4619        return false;
4620    }
4621
4622    IOMX::node_id nodeID;
4623    CHECK(msg->findInt32("node", (int32_t*)&nodeID));
4624    if (nodeID != mCodec->mNode) {
4625        ALOGE("Unexpected message for nodeID: %u, should have been %u", nodeID, mCodec->mNode);
4626        return false;
4627    }
4628    return true;
4629}
4630
4631bool ACodec::BaseState::onOMXMessageList(const sp<AMessage> &msg) {
4632    sp<RefBase> obj;
4633    CHECK(msg->findObject("messages", &obj));
4634    sp<MessageList> msgList = static_cast<MessageList *>(obj.get());
4635
4636    bool receivedRenderedEvents = false;
4637    for (std::list<sp<AMessage>>::const_iterator it = msgList->getList().cbegin();
4638          it != msgList->getList().cend(); ++it) {
4639        (*it)->setWhat(ACodec::kWhatOMXMessageItem);
4640        mCodec->handleMessage(*it);
4641        int32_t type;
4642        CHECK((*it)->findInt32("type", &type));
4643        if (type == omx_message::FRAME_RENDERED) {
4644            receivedRenderedEvents = true;
4645        }
4646    }
4647
4648    if (receivedRenderedEvents) {
4649        // NOTE: all buffers are rendered in this case
4650        mCodec->notifyOfRenderedFrames();
4651    }
4652    return true;
4653}
4654
4655bool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
4656    int32_t type;
4657    CHECK(msg->findInt32("type", &type));
4658
4659    switch (type) {
4660        case omx_message::EVENT:
4661        {
4662            int32_t event, data1, data2;
4663            CHECK(msg->findInt32("event", &event));
4664            CHECK(msg->findInt32("data1", &data1));
4665            CHECK(msg->findInt32("data2", &data2));
4666
4667            if (event == OMX_EventCmdComplete
4668                    && data1 == OMX_CommandFlush
4669                    && data2 == (int32_t)OMX_ALL) {
4670                // Use of this notification is not consistent across
4671                // implementations. We'll drop this notification and rely
4672                // on flush-complete notifications on the individual port
4673                // indices instead.
4674
4675                return true;
4676            }
4677
4678            return onOMXEvent(
4679                    static_cast<OMX_EVENTTYPE>(event),
4680                    static_cast<OMX_U32>(data1),
4681                    static_cast<OMX_U32>(data2));
4682        }
4683
4684        case omx_message::EMPTY_BUFFER_DONE:
4685        {
4686            IOMX::buffer_id bufferID;
4687            int32_t fenceFd;
4688
4689            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
4690            CHECK(msg->findInt32("fence_fd", &fenceFd));
4691
4692            return onOMXEmptyBufferDone(bufferID, fenceFd);
4693        }
4694
4695        case omx_message::FILL_BUFFER_DONE:
4696        {
4697            IOMX::buffer_id bufferID;
4698            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
4699
4700            int32_t rangeOffset, rangeLength, flags, fenceFd;
4701            int64_t timeUs;
4702
4703            CHECK(msg->findInt32("range_offset", &rangeOffset));
4704            CHECK(msg->findInt32("range_length", &rangeLength));
4705            CHECK(msg->findInt32("flags", &flags));
4706            CHECK(msg->findInt64("timestamp", &timeUs));
4707            CHECK(msg->findInt32("fence_fd", &fenceFd));
4708
4709            return onOMXFillBufferDone(
4710                    bufferID,
4711                    (size_t)rangeOffset, (size_t)rangeLength,
4712                    (OMX_U32)flags,
4713                    timeUs,
4714                    fenceFd);
4715        }
4716
4717        case omx_message::FRAME_RENDERED:
4718        {
4719            int64_t mediaTimeUs, systemNano;
4720
4721            CHECK(msg->findInt64("media_time_us", &mediaTimeUs));
4722            CHECK(msg->findInt64("system_nano", &systemNano));
4723
4724            return onOMXFrameRendered(
4725                    mediaTimeUs, systemNano);
4726        }
4727
4728        default:
4729            ALOGE("Unexpected message type: %d", type);
4730            return false;
4731    }
4732}
4733
4734bool ACodec::BaseState::onOMXFrameRendered(
4735        int64_t mediaTimeUs __unused, nsecs_t systemNano __unused) {
4736    // ignore outside of Executing and PortSettingsChanged states
4737    return true;
4738}
4739
4740bool ACodec::BaseState::onOMXEvent(
4741        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4742    if (event != OMX_EventError) {
4743        ALOGV("[%s] EVENT(%d, 0x%08x, 0x%08x)",
4744             mCodec->mComponentName.c_str(), event, data1, data2);
4745
4746        return false;
4747    }
4748
4749    ALOGE("[%s] ERROR(0x%08x)", mCodec->mComponentName.c_str(), data1);
4750
4751    // verify OMX component sends back an error we expect.
4752    OMX_ERRORTYPE omxError = (OMX_ERRORTYPE)data1;
4753    if (!isOMXError(omxError)) {
4754        ALOGW("Invalid OMX error %#x", omxError);
4755        omxError = OMX_ErrorUndefined;
4756    }
4757    mCodec->signalError(omxError);
4758
4759    return true;
4760}
4761
4762bool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID, int fenceFd) {
4763    ALOGV("[%s] onOMXEmptyBufferDone %u",
4764         mCodec->mComponentName.c_str(), bufferID);
4765
4766    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
4767    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
4768    if (status != BufferInfo::OWNED_BY_COMPONENT) {
4769        ALOGE("Wrong ownership in EBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
4770        mCodec->dumpBuffers(kPortIndexInput);
4771        if (fenceFd >= 0) {
4772            ::close(fenceFd);
4773        }
4774        return false;
4775    }
4776    info->mStatus = BufferInfo::OWNED_BY_US;
4777
4778    // input buffers cannot take fences, so wait for any fence now
4779    (void)mCodec->waitForFence(fenceFd, "onOMXEmptyBufferDone");
4780    fenceFd = -1;
4781
4782    // still save fence for completeness
4783    info->setWriteFence(fenceFd, "onOMXEmptyBufferDone");
4784
4785    // We're in "store-metadata-in-buffers" mode, the underlying
4786    // OMX component had access to data that's implicitly refcounted
4787    // by this "MediaBuffer" object. Now that the OMX component has
4788    // told us that it's done with the input buffer, we can decrement
4789    // the mediaBuffer's reference count.
4790    info->mData->setMediaBufferBase(NULL);
4791
4792    PortMode mode = getPortMode(kPortIndexInput);
4793
4794    switch (mode) {
4795        case KEEP_BUFFERS:
4796            break;
4797
4798        case RESUBMIT_BUFFERS:
4799            postFillThisBuffer(info);
4800            break;
4801
4802        case FREE_BUFFERS:
4803        default:
4804            ALOGE("SHOULD NOT REACH HERE: cannot free empty output buffers");
4805            return false;
4806    }
4807
4808    return true;
4809}
4810
4811void ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
4812    if (mCodec->mPortEOS[kPortIndexInput]) {
4813        return;
4814    }
4815
4816    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
4817
4818    sp<AMessage> notify = mCodec->mNotify->dup();
4819    notify->setInt32("what", CodecBase::kWhatFillThisBuffer);
4820    notify->setInt32("buffer-id", info->mBufferID);
4821
4822    info->mData->meta()->clear();
4823    notify->setBuffer("buffer", info->mData);
4824
4825    sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec);
4826    reply->setInt32("buffer-id", info->mBufferID);
4827
4828    notify->setMessage("reply", reply);
4829
4830    notify->post();
4831
4832    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
4833}
4834
4835void ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
4836    IOMX::buffer_id bufferID;
4837    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
4838    sp<ABuffer> buffer;
4839    int32_t err = OK;
4840    bool eos = false;
4841    PortMode mode = getPortMode(kPortIndexInput);
4842
4843    if (!msg->findBuffer("buffer", &buffer)) {
4844        /* these are unfilled buffers returned by client */
4845        CHECK(msg->findInt32("err", &err));
4846
4847        if (err == OK) {
4848            /* buffers with no errors are returned on MediaCodec.flush */
4849            mode = KEEP_BUFFERS;
4850        } else {
4851            ALOGV("[%s] saw error %d instead of an input buffer",
4852                 mCodec->mComponentName.c_str(), err);
4853            eos = true;
4854        }
4855
4856        buffer.clear();
4857    }
4858
4859    int32_t tmp;
4860    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
4861        eos = true;
4862        err = ERROR_END_OF_STREAM;
4863    }
4864
4865    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
4866    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
4867    if (status != BufferInfo::OWNED_BY_UPSTREAM) {
4868        ALOGE("Wrong ownership in IBF: %s(%d) buffer #%u", _asString(status), status, bufferID);
4869        mCodec->dumpBuffers(kPortIndexInput);
4870        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
4871        return;
4872    }
4873
4874    info->mStatus = BufferInfo::OWNED_BY_US;
4875
4876    switch (mode) {
4877        case KEEP_BUFFERS:
4878        {
4879            if (eos) {
4880                if (!mCodec->mPortEOS[kPortIndexInput]) {
4881                    mCodec->mPortEOS[kPortIndexInput] = true;
4882                    mCodec->mInputEOSResult = err;
4883                }
4884            }
4885            break;
4886        }
4887
4888        case RESUBMIT_BUFFERS:
4889        {
4890            if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
4891                // Do not send empty input buffer w/o EOS to the component.
4892                if (buffer->size() == 0 && !eos) {
4893                    postFillThisBuffer(info);
4894                    break;
4895                }
4896
4897                int64_t timeUs;
4898                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
4899
4900                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
4901
4902                int32_t isCSD;
4903                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
4904                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
4905                }
4906
4907                if (eos) {
4908                    flags |= OMX_BUFFERFLAG_EOS;
4909                }
4910
4911                if (buffer != info->mData) {
4912                    ALOGV("[%s] Needs to copy input data for buffer %u. (%p != %p)",
4913                         mCodec->mComponentName.c_str(),
4914                         bufferID,
4915                         buffer.get(), info->mData.get());
4916
4917                    if (buffer->size() > info->mData->capacity()) {
4918                        ALOGE("data size (%zu) is greated than buffer capacity (%zu)",
4919                                buffer->size(),           // this is the data received
4920                                info->mData->capacity()); // this is out buffer size
4921                        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
4922                        return;
4923                    }
4924                    memcpy(info->mData->data(), buffer->data(), buffer->size());
4925                }
4926
4927                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
4928                    ALOGV("[%s] calling emptyBuffer %u w/ codec specific data",
4929                         mCodec->mComponentName.c_str(), bufferID);
4930                } else if (flags & OMX_BUFFERFLAG_EOS) {
4931                    ALOGV("[%s] calling emptyBuffer %u w/ EOS",
4932                         mCodec->mComponentName.c_str(), bufferID);
4933                } else {
4934#if TRACK_BUFFER_TIMING
4935                    ALOGI("[%s] calling emptyBuffer %u w/ time %lld us",
4936                         mCodec->mComponentName.c_str(), bufferID, (long long)timeUs);
4937#else
4938                    ALOGV("[%s] calling emptyBuffer %u w/ time %lld us",
4939                         mCodec->mComponentName.c_str(), bufferID, (long long)timeUs);
4940#endif
4941                }
4942
4943#if TRACK_BUFFER_TIMING
4944                ACodec::BufferStats stats;
4945                stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
4946                stats.mFillBufferDoneTimeUs = -1ll;
4947                mCodec->mBufferStats.add(timeUs, stats);
4948#endif
4949
4950                if (mCodec->storingMetadataInDecodedBuffers()) {
4951                    // try to submit an output buffer for each input buffer
4952                    PortMode outputMode = getPortMode(kPortIndexOutput);
4953
4954                    ALOGV("MetadataBuffersToSubmit=%u portMode=%s",
4955                            mCodec->mMetadataBuffersToSubmit,
4956                            (outputMode == FREE_BUFFERS ? "FREE" :
4957                             outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
4958                    if (outputMode == RESUBMIT_BUFFERS) {
4959                        mCodec->submitOutputMetadataBuffer();
4960                    }
4961                }
4962                info->checkReadFence("onInputBufferFilled");
4963                status_t err2 = mCodec->mOMX->emptyBuffer(
4964                    mCodec->mNode,
4965                    bufferID,
4966                    0,
4967                    buffer->size(),
4968                    flags,
4969                    timeUs,
4970                    info->mFenceFd);
4971                info->mFenceFd = -1;
4972                if (err2 != OK) {
4973                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err2));
4974                    return;
4975                }
4976                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4977
4978                if (!eos && err == OK) {
4979                    getMoreInputDataIfPossible();
4980                } else {
4981                    ALOGV("[%s] Signalled EOS (%d) on the input port",
4982                         mCodec->mComponentName.c_str(), err);
4983
4984                    mCodec->mPortEOS[kPortIndexInput] = true;
4985                    mCodec->mInputEOSResult = err;
4986                }
4987            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
4988                if (err != OK && err != ERROR_END_OF_STREAM) {
4989                    ALOGV("[%s] Signalling EOS on the input port due to error %d",
4990                         mCodec->mComponentName.c_str(), err);
4991                } else {
4992                    ALOGV("[%s] Signalling EOS on the input port",
4993                         mCodec->mComponentName.c_str());
4994                }
4995
4996                ALOGV("[%s] calling emptyBuffer %u signalling EOS",
4997                     mCodec->mComponentName.c_str(), bufferID);
4998
4999                info->checkReadFence("onInputBufferFilled");
5000                status_t err2 = mCodec->mOMX->emptyBuffer(
5001                        mCodec->mNode,
5002                        bufferID,
5003                        0,
5004                        0,
5005                        OMX_BUFFERFLAG_EOS,
5006                        0,
5007                        info->mFenceFd);
5008                info->mFenceFd = -1;
5009                if (err2 != OK) {
5010                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err2));
5011                    return;
5012                }
5013                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
5014
5015                mCodec->mPortEOS[kPortIndexInput] = true;
5016                mCodec->mInputEOSResult = err;
5017            }
5018            break;
5019        }
5020
5021        case FREE_BUFFERS:
5022            break;
5023
5024        default:
5025            ALOGE("invalid port mode: %d", mode);
5026            break;
5027    }
5028}
5029
5030void ACodec::BaseState::getMoreInputDataIfPossible() {
5031    if (mCodec->mPortEOS[kPortIndexInput]) {
5032        return;
5033    }
5034
5035    BufferInfo *eligible = NULL;
5036
5037    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
5038        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
5039
5040#if 0
5041        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
5042            // There's already a "read" pending.
5043            return;
5044        }
5045#endif
5046
5047        if (info->mStatus == BufferInfo::OWNED_BY_US) {
5048            eligible = info;
5049        }
5050    }
5051
5052    if (eligible == NULL) {
5053        return;
5054    }
5055
5056    postFillThisBuffer(eligible);
5057}
5058
5059bool ACodec::BaseState::onOMXFillBufferDone(
5060        IOMX::buffer_id bufferID,
5061        size_t rangeOffset, size_t rangeLength,
5062        OMX_U32 flags,
5063        int64_t timeUs,
5064        int fenceFd) {
5065    ALOGV("[%s] onOMXFillBufferDone %u time %" PRId64 " us, flags = 0x%08x",
5066         mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
5067
5068    ssize_t index;
5069    status_t err= OK;
5070
5071#if TRACK_BUFFER_TIMING
5072    index = mCodec->mBufferStats.indexOfKey(timeUs);
5073    if (index >= 0) {
5074        ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
5075        stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
5076
5077        ALOGI("frame PTS %lld: %lld",
5078                timeUs,
5079                stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
5080
5081        mCodec->mBufferStats.removeItemsAt(index);
5082        stats = NULL;
5083    }
5084#endif
5085
5086    BufferInfo *info =
5087        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
5088    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
5089    if (status != BufferInfo::OWNED_BY_COMPONENT) {
5090        ALOGE("Wrong ownership in FBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
5091        mCodec->dumpBuffers(kPortIndexOutput);
5092        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
5093        if (fenceFd >= 0) {
5094            ::close(fenceFd);
5095        }
5096        return true;
5097    }
5098
5099    info->mDequeuedAt = ++mCodec->mDequeueCounter;
5100    info->mStatus = BufferInfo::OWNED_BY_US;
5101
5102    if (info->mRenderInfo != NULL) {
5103        // The fence for an emptied buffer must have signaled, but there still could be queued
5104        // or out-of-order dequeued buffers in the render queue prior to this buffer. Drop these,
5105        // as we will soon requeue this buffer to the surface. While in theory we could still keep
5106        // track of buffers that are requeued to the surface, it is better to add support to the
5107        // buffer-queue to notify us of released buffers and their fences (in the future).
5108        mCodec->notifyOfRenderedFrames(true /* dropIncomplete */);
5109    }
5110
5111    // byte buffers cannot take fences, so wait for any fence now
5112    if (mCodec->mNativeWindow == NULL) {
5113        (void)mCodec->waitForFence(fenceFd, "onOMXFillBufferDone");
5114        fenceFd = -1;
5115    }
5116    info->setReadFence(fenceFd, "onOMXFillBufferDone");
5117
5118    PortMode mode = getPortMode(kPortIndexOutput);
5119
5120    switch (mode) {
5121        case KEEP_BUFFERS:
5122            break;
5123
5124        case RESUBMIT_BUFFERS:
5125        {
5126            if (rangeLength == 0 && (!(flags & OMX_BUFFERFLAG_EOS)
5127                    || mCodec->mPortEOS[kPortIndexOutput])) {
5128                ALOGV("[%s] calling fillBuffer %u",
5129                     mCodec->mComponentName.c_str(), info->mBufferID);
5130
5131                err = mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID, info->mFenceFd);
5132                info->mFenceFd = -1;
5133                if (err != OK) {
5134                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5135                    return true;
5136                }
5137
5138                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
5139                break;
5140            }
5141
5142            sp<AMessage> reply =
5143                new AMessage(kWhatOutputBufferDrained, mCodec);
5144
5145            if (!mCodec->mSentFormat && rangeLength > 0) {
5146                mCodec->sendFormatChange(reply);
5147            }
5148            if (mCodec->usingMetadataOnEncoderOutput()) {
5149                native_handle_t *handle = NULL;
5150                VideoGrallocMetadata &grallocMeta = *(VideoGrallocMetadata *)info->mData->data();
5151                VideoNativeMetadata &nativeMeta = *(VideoNativeMetadata *)info->mData->data();
5152                if (info->mData->size() >= sizeof(grallocMeta)
5153                        && grallocMeta.eType == kMetadataBufferTypeGrallocSource) {
5154                    handle = (native_handle_t *)(uintptr_t)grallocMeta.pHandle;
5155                } else if (info->mData->size() >= sizeof(nativeMeta)
5156                        && nativeMeta.eType == kMetadataBufferTypeANWBuffer) {
5157#ifdef OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
5158                    // ANativeWindowBuffer is only valid on 32-bit/mediaserver process
5159                    handle = NULL;
5160#else
5161                    handle = (native_handle_t *)nativeMeta.pBuffer->handle;
5162#endif
5163                }
5164                info->mData->meta()->setPointer("handle", handle);
5165                info->mData->meta()->setInt32("rangeOffset", rangeOffset);
5166                info->mData->meta()->setInt32("rangeLength", rangeLength);
5167            } else {
5168                info->mData->setRange(rangeOffset, rangeLength);
5169            }
5170#if 0
5171            if (mCodec->mNativeWindow == NULL) {
5172                if (IsIDR(info->mData)) {
5173                    ALOGI("IDR frame");
5174                }
5175            }
5176#endif
5177
5178            if (mCodec->mSkipCutBuffer != NULL) {
5179                mCodec->mSkipCutBuffer->submit(info->mData);
5180            }
5181            info->mData->meta()->setInt64("timeUs", timeUs);
5182
5183            sp<AMessage> notify = mCodec->mNotify->dup();
5184            notify->setInt32("what", CodecBase::kWhatDrainThisBuffer);
5185            notify->setInt32("buffer-id", info->mBufferID);
5186            notify->setBuffer("buffer", info->mData);
5187            notify->setInt32("flags", flags);
5188
5189            reply->setInt32("buffer-id", info->mBufferID);
5190
5191            notify->setMessage("reply", reply);
5192
5193            notify->post();
5194
5195            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
5196
5197            if (flags & OMX_BUFFERFLAG_EOS) {
5198                ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
5199
5200                sp<AMessage> notify = mCodec->mNotify->dup();
5201                notify->setInt32("what", CodecBase::kWhatEOS);
5202                notify->setInt32("err", mCodec->mInputEOSResult);
5203                notify->post();
5204
5205                mCodec->mPortEOS[kPortIndexOutput] = true;
5206            }
5207            break;
5208        }
5209
5210        case FREE_BUFFERS:
5211            err = mCodec->freeBuffer(kPortIndexOutput, index);
5212            if (err != OK) {
5213                mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5214                return true;
5215            }
5216            break;
5217
5218        default:
5219            ALOGE("Invalid port mode: %d", mode);
5220            return false;
5221    }
5222
5223    return true;
5224}
5225
5226void ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
5227    IOMX::buffer_id bufferID;
5228    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
5229    ssize_t index;
5230    BufferInfo *info = mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
5231    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
5232    if (status != BufferInfo::OWNED_BY_DOWNSTREAM) {
5233        ALOGE("Wrong ownership in OBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
5234        mCodec->dumpBuffers(kPortIndexOutput);
5235        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
5236        return;
5237    }
5238
5239    android_native_rect_t crop;
5240    if (msg->findRect("crop", &crop.left, &crop.top, &crop.right, &crop.bottom)) {
5241        status_t err = native_window_set_crop(mCodec->mNativeWindow.get(), &crop);
5242        ALOGW_IF(err != NO_ERROR, "failed to set crop: %d", err);
5243    }
5244
5245    int32_t render;
5246    if (mCodec->mNativeWindow != NULL
5247            && msg->findInt32("render", &render) && render != 0
5248            && info->mData != NULL && info->mData->size() != 0) {
5249        ATRACE_NAME("render");
5250        // The client wants this buffer to be rendered.
5251
5252        // save buffers sent to the surface so we can get render time when they return
5253        int64_t mediaTimeUs = -1;
5254        info->mData->meta()->findInt64("timeUs", &mediaTimeUs);
5255        if (mediaTimeUs >= 0) {
5256            mCodec->mRenderTracker.onFrameQueued(
5257                    mediaTimeUs, info->mGraphicBuffer, new Fence(::dup(info->mFenceFd)));
5258        }
5259
5260        int64_t timestampNs = 0;
5261        if (!msg->findInt64("timestampNs", &timestampNs)) {
5262            // use media timestamp if client did not request a specific render timestamp
5263            if (info->mData->meta()->findInt64("timeUs", &timestampNs)) {
5264                ALOGV("using buffer PTS of %lld", (long long)timestampNs);
5265                timestampNs *= 1000;
5266            }
5267        }
5268
5269        status_t err;
5270        err = native_window_set_buffers_timestamp(mCodec->mNativeWindow.get(), timestampNs);
5271        ALOGW_IF(err != NO_ERROR, "failed to set buffer timestamp: %d", err);
5272
5273        info->checkReadFence("onOutputBufferDrained before queueBuffer");
5274        err = mCodec->mNativeWindow->queueBuffer(
5275                    mCodec->mNativeWindow.get(), info->mGraphicBuffer.get(), info->mFenceFd);
5276        info->mFenceFd = -1;
5277        if (err == OK) {
5278            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
5279        } else {
5280            ALOGE("queueBuffer failed in onOutputBufferDrained: %d", err);
5281            mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5282            info->mStatus = BufferInfo::OWNED_BY_US;
5283            // keeping read fence as write fence to avoid clobbering
5284            info->mIsReadFence = false;
5285        }
5286    } else {
5287        if (mCodec->mNativeWindow != NULL &&
5288            (info->mData == NULL || info->mData->size() != 0)) {
5289            // move read fence into write fence to avoid clobbering
5290            info->mIsReadFence = false;
5291            ATRACE_NAME("frame-drop");
5292        }
5293        info->mStatus = BufferInfo::OWNED_BY_US;
5294    }
5295
5296    PortMode mode = getPortMode(kPortIndexOutput);
5297
5298    switch (mode) {
5299        case KEEP_BUFFERS:
5300        {
5301            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
5302
5303            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
5304                // We cannot resubmit the buffer we just rendered, dequeue
5305                // the spare instead.
5306
5307                info = mCodec->dequeueBufferFromNativeWindow();
5308            }
5309            break;
5310        }
5311
5312        case RESUBMIT_BUFFERS:
5313        {
5314            if (!mCodec->mPortEOS[kPortIndexOutput]) {
5315                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
5316                    // We cannot resubmit the buffer we just rendered, dequeue
5317                    // the spare instead.
5318
5319                    info = mCodec->dequeueBufferFromNativeWindow();
5320                }
5321
5322                if (info != NULL) {
5323                    ALOGV("[%s] calling fillBuffer %u",
5324                         mCodec->mComponentName.c_str(), info->mBufferID);
5325                    info->checkWriteFence("onOutputBufferDrained::RESUBMIT_BUFFERS");
5326                    status_t err = mCodec->mOMX->fillBuffer(
5327                            mCodec->mNode, info->mBufferID, info->mFenceFd);
5328                    info->mFenceFd = -1;
5329                    if (err == OK) {
5330                        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
5331                    } else {
5332                        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5333                    }
5334                }
5335            }
5336            break;
5337        }
5338
5339        case FREE_BUFFERS:
5340        {
5341            status_t err = mCodec->freeBuffer(kPortIndexOutput, index);
5342            if (err != OK) {
5343                mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5344            }
5345            break;
5346        }
5347
5348        default:
5349            ALOGE("Invalid port mode: %d", mode);
5350            return;
5351    }
5352}
5353
5354////////////////////////////////////////////////////////////////////////////////
5355
5356ACodec::UninitializedState::UninitializedState(ACodec *codec)
5357    : BaseState(codec) {
5358}
5359
5360void ACodec::UninitializedState::stateEntered() {
5361    ALOGV("Now uninitialized");
5362
5363    if (mDeathNotifier != NULL) {
5364        IInterface::asBinder(mCodec->mOMX)->unlinkToDeath(mDeathNotifier);
5365        mDeathNotifier.clear();
5366    }
5367
5368    mCodec->mNativeWindow.clear();
5369    mCodec->mNativeWindowUsageBits = 0;
5370    mCodec->mNode = 0;
5371    mCodec->mOMX.clear();
5372    mCodec->mQuirks = 0;
5373    mCodec->mFlags = 0;
5374    mCodec->mInputMetadataType = kMetadataBufferTypeInvalid;
5375    mCodec->mOutputMetadataType = kMetadataBufferTypeInvalid;
5376    mCodec->mComponentName.clear();
5377}
5378
5379bool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
5380    bool handled = false;
5381
5382    switch (msg->what()) {
5383        case ACodec::kWhatSetup:
5384        {
5385            onSetup(msg);
5386
5387            handled = true;
5388            break;
5389        }
5390
5391        case ACodec::kWhatAllocateComponent:
5392        {
5393            onAllocateComponent(msg);
5394            handled = true;
5395            break;
5396        }
5397
5398        case ACodec::kWhatShutdown:
5399        {
5400            int32_t keepComponentAllocated;
5401            CHECK(msg->findInt32(
5402                        "keepComponentAllocated", &keepComponentAllocated));
5403            ALOGW_IF(keepComponentAllocated,
5404                     "cannot keep component allocated on shutdown in Uninitialized state");
5405
5406            sp<AMessage> notify = mCodec->mNotify->dup();
5407            notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
5408            notify->post();
5409
5410            handled = true;
5411            break;
5412        }
5413
5414        case ACodec::kWhatFlush:
5415        {
5416            sp<AMessage> notify = mCodec->mNotify->dup();
5417            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
5418            notify->post();
5419
5420            handled = true;
5421            break;
5422        }
5423
5424        case ACodec::kWhatReleaseCodecInstance:
5425        {
5426            // nothing to do, as we have already signaled shutdown
5427            handled = true;
5428            break;
5429        }
5430
5431        default:
5432            return BaseState::onMessageReceived(msg);
5433    }
5434
5435    return handled;
5436}
5437
5438void ACodec::UninitializedState::onSetup(
5439        const sp<AMessage> &msg) {
5440    if (onAllocateComponent(msg)
5441            && mCodec->mLoadedState->onConfigureComponent(msg)) {
5442        mCodec->mLoadedState->onStart();
5443    }
5444}
5445
5446bool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
5447    ALOGV("onAllocateComponent");
5448
5449    CHECK(mCodec->mNode == 0);
5450
5451    OMXClient client;
5452    if (client.connect() != OK) {
5453        mCodec->signalError(OMX_ErrorUndefined, NO_INIT);
5454        return false;
5455    }
5456
5457    sp<IOMX> omx = client.interface();
5458
5459    sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec);
5460
5461    mDeathNotifier = new DeathNotifier(notify);
5462    if (IInterface::asBinder(omx)->linkToDeath(mDeathNotifier) != OK) {
5463        // This was a local binder, if it dies so do we, we won't care
5464        // about any notifications in the afterlife.
5465        mDeathNotifier.clear();
5466    }
5467
5468    Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs;
5469
5470    AString mime;
5471
5472    AString componentName;
5473    uint32_t quirks = 0;
5474    int32_t encoder = false;
5475    if (msg->findString("componentName", &componentName)) {
5476        ssize_t index = matchingCodecs.add();
5477        OMXCodec::CodecNameAndQuirks *entry = &matchingCodecs.editItemAt(index);
5478        entry->mName = String8(componentName.c_str());
5479
5480        if (!OMXCodec::findCodecQuirks(
5481                    componentName.c_str(), &entry->mQuirks)) {
5482            entry->mQuirks = 0;
5483        }
5484    } else {
5485        CHECK(msg->findString("mime", &mime));
5486
5487        if (!msg->findInt32("encoder", &encoder)) {
5488            encoder = false;
5489        }
5490
5491        OMXCodec::findMatchingCodecs(
5492                mime.c_str(),
5493                encoder, // createEncoder
5494                NULL,  // matchComponentName
5495                0,     // flags
5496                &matchingCodecs);
5497    }
5498
5499    sp<CodecObserver> observer = new CodecObserver;
5500    IOMX::node_id node = 0;
5501
5502    status_t err = NAME_NOT_FOUND;
5503    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
5504            ++matchIndex) {
5505        componentName = matchingCodecs.itemAt(matchIndex).mName.string();
5506        quirks = matchingCodecs.itemAt(matchIndex).mQuirks;
5507
5508        pid_t tid = gettid();
5509        int prevPriority = androidGetThreadPriority(tid);
5510        androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
5511        err = omx->allocateNode(componentName.c_str(), observer, &node);
5512        androidSetThreadPriority(tid, prevPriority);
5513
5514        if (err == OK) {
5515            break;
5516        } else {
5517            ALOGW("Allocating component '%s' failed, try next one.", componentName.c_str());
5518        }
5519
5520        node = 0;
5521    }
5522
5523    if (node == 0) {
5524        if (!mime.empty()) {
5525            ALOGE("Unable to instantiate a %scoder for type '%s' with err %#x.",
5526                    encoder ? "en" : "de", mime.c_str(), err);
5527        } else {
5528            ALOGE("Unable to instantiate codec '%s' with err %#x.", componentName.c_str(), err);
5529        }
5530
5531        mCodec->signalError((OMX_ERRORTYPE)err, makeNoSideEffectStatus(err));
5532        return false;
5533    }
5534
5535    notify = new AMessage(kWhatOMXMessageList, mCodec);
5536    observer->setNotificationMessage(notify);
5537
5538    mCodec->mComponentName = componentName;
5539    mCodec->mRenderTracker.setComponentName(componentName);
5540    mCodec->mFlags = 0;
5541
5542    if (componentName.endsWith(".secure")) {
5543        mCodec->mFlags |= kFlagIsSecure;
5544        mCodec->mFlags |= kFlagIsGrallocUsageProtected;
5545        mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
5546    }
5547
5548    mCodec->mQuirks = quirks;
5549    mCodec->mOMX = omx;
5550    mCodec->mNode = node;
5551
5552    {
5553        sp<AMessage> notify = mCodec->mNotify->dup();
5554        notify->setInt32("what", CodecBase::kWhatComponentAllocated);
5555        notify->setString("componentName", mCodec->mComponentName.c_str());
5556        notify->post();
5557    }
5558
5559    mCodec->changeState(mCodec->mLoadedState);
5560
5561    return true;
5562}
5563
5564////////////////////////////////////////////////////////////////////////////////
5565
5566ACodec::LoadedState::LoadedState(ACodec *codec)
5567    : BaseState(codec) {
5568}
5569
5570void ACodec::LoadedState::stateEntered() {
5571    ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
5572
5573    mCodec->mPortEOS[kPortIndexInput] =
5574        mCodec->mPortEOS[kPortIndexOutput] = false;
5575
5576    mCodec->mInputEOSResult = OK;
5577
5578    mCodec->mDequeueCounter = 0;
5579    mCodec->mMetadataBuffersToSubmit = 0;
5580    mCodec->mRepeatFrameDelayUs = -1ll;
5581    mCodec->mInputFormat.clear();
5582    mCodec->mOutputFormat.clear();
5583    mCodec->mBaseOutputFormat.clear();
5584
5585    if (mCodec->mShutdownInProgress) {
5586        bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
5587
5588        mCodec->mShutdownInProgress = false;
5589        mCodec->mKeepComponentAllocated = false;
5590
5591        onShutdown(keepComponentAllocated);
5592    }
5593    mCodec->mExplicitShutdown = false;
5594
5595    mCodec->processDeferredMessages();
5596}
5597
5598void ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
5599    if (!keepComponentAllocated) {
5600        (void)mCodec->mOMX->freeNode(mCodec->mNode);
5601
5602        mCodec->changeState(mCodec->mUninitializedState);
5603    }
5604
5605    if (mCodec->mExplicitShutdown) {
5606        sp<AMessage> notify = mCodec->mNotify->dup();
5607        notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
5608        notify->post();
5609        mCodec->mExplicitShutdown = false;
5610    }
5611}
5612
5613bool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
5614    bool handled = false;
5615
5616    switch (msg->what()) {
5617        case ACodec::kWhatConfigureComponent:
5618        {
5619            onConfigureComponent(msg);
5620            handled = true;
5621            break;
5622        }
5623
5624        case ACodec::kWhatCreateInputSurface:
5625        {
5626            onCreateInputSurface(msg);
5627            handled = true;
5628            break;
5629        }
5630
5631        case ACodec::kWhatSetInputSurface:
5632        {
5633            onSetInputSurface(msg);
5634            handled = true;
5635            break;
5636        }
5637
5638        case ACodec::kWhatStart:
5639        {
5640            onStart();
5641            handled = true;
5642            break;
5643        }
5644
5645        case ACodec::kWhatShutdown:
5646        {
5647            int32_t keepComponentAllocated;
5648            CHECK(msg->findInt32(
5649                        "keepComponentAllocated", &keepComponentAllocated));
5650
5651            mCodec->mExplicitShutdown = true;
5652            onShutdown(keepComponentAllocated);
5653
5654            handled = true;
5655            break;
5656        }
5657
5658        case ACodec::kWhatFlush:
5659        {
5660            sp<AMessage> notify = mCodec->mNotify->dup();
5661            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
5662            notify->post();
5663
5664            handled = true;
5665            break;
5666        }
5667
5668        default:
5669            return BaseState::onMessageReceived(msg);
5670    }
5671
5672    return handled;
5673}
5674
5675bool ACodec::LoadedState::onConfigureComponent(
5676        const sp<AMessage> &msg) {
5677    ALOGV("onConfigureComponent");
5678
5679    CHECK(mCodec->mNode != 0);
5680
5681    status_t err = OK;
5682    AString mime;
5683    if (!msg->findString("mime", &mime)) {
5684        err = BAD_VALUE;
5685    } else {
5686        err = mCodec->configureCodec(mime.c_str(), msg);
5687    }
5688    if (err != OK) {
5689        ALOGE("[%s] configureCodec returning error %d",
5690              mCodec->mComponentName.c_str(), err);
5691
5692        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5693        return false;
5694    }
5695
5696    {
5697        sp<AMessage> notify = mCodec->mNotify->dup();
5698        notify->setInt32("what", CodecBase::kWhatComponentConfigured);
5699        notify->setMessage("input-format", mCodec->mInputFormat);
5700        notify->setMessage("output-format", mCodec->mOutputFormat);
5701        notify->post();
5702    }
5703
5704    return true;
5705}
5706
5707status_t ACodec::LoadedState::setupInputSurface() {
5708    status_t err = OK;
5709
5710    if (mCodec->mRepeatFrameDelayUs > 0ll) {
5711        err = mCodec->mOMX->setInternalOption(
5712                mCodec->mNode,
5713                kPortIndexInput,
5714                IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY,
5715                &mCodec->mRepeatFrameDelayUs,
5716                sizeof(mCodec->mRepeatFrameDelayUs));
5717
5718        if (err != OK) {
5719            ALOGE("[%s] Unable to configure option to repeat previous "
5720                  "frames (err %d)",
5721                  mCodec->mComponentName.c_str(),
5722                  err);
5723            return err;
5724        }
5725    }
5726
5727    if (mCodec->mMaxPtsGapUs > 0ll) {
5728        err = mCodec->mOMX->setInternalOption(
5729                mCodec->mNode,
5730                kPortIndexInput,
5731                IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP,
5732                &mCodec->mMaxPtsGapUs,
5733                sizeof(mCodec->mMaxPtsGapUs));
5734
5735        if (err != OK) {
5736            ALOGE("[%s] Unable to configure max timestamp gap (err %d)",
5737                    mCodec->mComponentName.c_str(),
5738                    err);
5739            return err;
5740        }
5741    }
5742
5743    if (mCodec->mMaxFps > 0) {
5744        err = mCodec->mOMX->setInternalOption(
5745                mCodec->mNode,
5746                kPortIndexInput,
5747                IOMX::INTERNAL_OPTION_MAX_FPS,
5748                &mCodec->mMaxFps,
5749                sizeof(mCodec->mMaxFps));
5750
5751        if (err != OK) {
5752            ALOGE("[%s] Unable to configure max fps (err %d)",
5753                    mCodec->mComponentName.c_str(),
5754                    err);
5755            return err;
5756        }
5757    }
5758
5759    if (mCodec->mTimePerCaptureUs > 0ll
5760            && mCodec->mTimePerFrameUs > 0ll) {
5761        int64_t timeLapse[2];
5762        timeLapse[0] = mCodec->mTimePerFrameUs;
5763        timeLapse[1] = mCodec->mTimePerCaptureUs;
5764        err = mCodec->mOMX->setInternalOption(
5765                mCodec->mNode,
5766                kPortIndexInput,
5767                IOMX::INTERNAL_OPTION_TIME_LAPSE,
5768                &timeLapse[0],
5769                sizeof(timeLapse));
5770
5771        if (err != OK) {
5772            ALOGE("[%s] Unable to configure time lapse (err %d)",
5773                    mCodec->mComponentName.c_str(),
5774                    err);
5775            return err;
5776        }
5777    }
5778
5779    if (mCodec->mCreateInputBuffersSuspended) {
5780        bool suspend = true;
5781        err = mCodec->mOMX->setInternalOption(
5782                mCodec->mNode,
5783                kPortIndexInput,
5784                IOMX::INTERNAL_OPTION_SUSPEND,
5785                &suspend,
5786                sizeof(suspend));
5787
5788        if (err != OK) {
5789            ALOGE("[%s] Unable to configure option to suspend (err %d)",
5790                  mCodec->mComponentName.c_str(),
5791                  err);
5792            return err;
5793        }
5794    }
5795
5796    uint32_t usageBits;
5797    if (mCodec->mOMX->getParameter(
5798            mCodec->mNode, (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits,
5799            &usageBits, sizeof(usageBits)) == OK) {
5800        mCodec->mInputFormat->setInt32(
5801                "using-sw-read-often", !!(usageBits & GRALLOC_USAGE_SW_READ_OFTEN));
5802    }
5803
5804    return OK;
5805}
5806
5807void ACodec::LoadedState::onCreateInputSurface(
5808        const sp<AMessage> & /* msg */) {
5809    ALOGV("onCreateInputSurface");
5810
5811    sp<AMessage> notify = mCodec->mNotify->dup();
5812    notify->setInt32("what", CodecBase::kWhatInputSurfaceCreated);
5813
5814    sp<IGraphicBufferProducer> bufferProducer;
5815    status_t err = mCodec->mOMX->createInputSurface(
5816            mCodec->mNode, kPortIndexInput, &bufferProducer, &mCodec->mInputMetadataType);
5817
5818    if (err == OK) {
5819        err = setupInputSurface();
5820    }
5821
5822    if (err == OK) {
5823        notify->setObject("input-surface",
5824                new BufferProducerWrapper(bufferProducer));
5825    } else {
5826        // Can't use mCodec->signalError() here -- MediaCodec won't forward
5827        // the error through because it's in the "configured" state.  We
5828        // send a kWhatInputSurfaceCreated with an error value instead.
5829        ALOGE("[%s] onCreateInputSurface returning error %d",
5830                mCodec->mComponentName.c_str(), err);
5831        notify->setInt32("err", err);
5832    }
5833    notify->post();
5834}
5835
5836void ACodec::LoadedState::onSetInputSurface(
5837        const sp<AMessage> &msg) {
5838    ALOGV("onSetInputSurface");
5839
5840    sp<AMessage> notify = mCodec->mNotify->dup();
5841    notify->setInt32("what", CodecBase::kWhatInputSurfaceAccepted);
5842
5843    sp<RefBase> obj;
5844    CHECK(msg->findObject("input-surface", &obj));
5845    sp<PersistentSurface> surface = static_cast<PersistentSurface *>(obj.get());
5846
5847    status_t err = mCodec->mOMX->setInputSurface(
5848            mCodec->mNode, kPortIndexInput, surface->getBufferConsumer(),
5849            &mCodec->mInputMetadataType);
5850
5851    if (err == OK) {
5852        err = setupInputSurface();
5853    }
5854
5855    if (err != OK) {
5856        // Can't use mCodec->signalError() here -- MediaCodec won't forward
5857        // the error through because it's in the "configured" state.  We
5858        // send a kWhatInputSurfaceAccepted with an error value instead.
5859        ALOGE("[%s] onSetInputSurface returning error %d",
5860                mCodec->mComponentName.c_str(), err);
5861        notify->setInt32("err", err);
5862    }
5863    notify->post();
5864}
5865
5866void ACodec::LoadedState::onStart() {
5867    ALOGV("onStart");
5868
5869    status_t err = mCodec->mOMX->sendCommand(mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle);
5870    if (err != OK) {
5871        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5872    } else {
5873        mCodec->changeState(mCodec->mLoadedToIdleState);
5874    }
5875}
5876
5877////////////////////////////////////////////////////////////////////////////////
5878
5879ACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
5880    : BaseState(codec) {
5881}
5882
5883void ACodec::LoadedToIdleState::stateEntered() {
5884    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
5885
5886    status_t err;
5887    if ((err = allocateBuffers()) != OK) {
5888        ALOGE("Failed to allocate buffers after transitioning to IDLE state "
5889             "(error 0x%08x)",
5890             err);
5891
5892        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5893
5894        mCodec->changeState(mCodec->mLoadedState);
5895    }
5896}
5897
5898status_t ACodec::LoadedToIdleState::allocateBuffers() {
5899    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
5900
5901    if (err != OK) {
5902        return err;
5903    }
5904
5905    return mCodec->allocateBuffersOnPort(kPortIndexOutput);
5906}
5907
5908bool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
5909    switch (msg->what()) {
5910        case kWhatSetParameters:
5911        case kWhatShutdown:
5912        {
5913            mCodec->deferMessage(msg);
5914            return true;
5915        }
5916
5917        case kWhatSignalEndOfInputStream:
5918        {
5919            mCodec->onSignalEndOfInputStream();
5920            return true;
5921        }
5922
5923        case kWhatResume:
5924        {
5925            // We'll be active soon enough.
5926            return true;
5927        }
5928
5929        case kWhatFlush:
5930        {
5931            // We haven't even started yet, so we're flushed alright...
5932            sp<AMessage> notify = mCodec->mNotify->dup();
5933            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
5934            notify->post();
5935            return true;
5936        }
5937
5938        default:
5939            return BaseState::onMessageReceived(msg);
5940    }
5941}
5942
5943bool ACodec::LoadedToIdleState::onOMXEvent(
5944        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5945    switch (event) {
5946        case OMX_EventCmdComplete:
5947        {
5948            status_t err = OK;
5949            if (data1 != (OMX_U32)OMX_CommandStateSet
5950                    || data2 != (OMX_U32)OMX_StateIdle) {
5951                ALOGE("Unexpected command completion in LoadedToIdleState: %s(%u) %s(%u)",
5952                        asString((OMX_COMMANDTYPE)data1), data1,
5953                        asString((OMX_STATETYPE)data2), data2);
5954                err = FAILED_TRANSACTION;
5955            }
5956
5957            if (err == OK) {
5958                err = mCodec->mOMX->sendCommand(
5959                    mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting);
5960            }
5961
5962            if (err != OK) {
5963                mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5964            } else {
5965                mCodec->changeState(mCodec->mIdleToExecutingState);
5966            }
5967
5968            return true;
5969        }
5970
5971        default:
5972            return BaseState::onOMXEvent(event, data1, data2);
5973    }
5974}
5975
5976////////////////////////////////////////////////////////////////////////////////
5977
5978ACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
5979    : BaseState(codec) {
5980}
5981
5982void ACodec::IdleToExecutingState::stateEntered() {
5983    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
5984}
5985
5986bool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
5987    switch (msg->what()) {
5988        case kWhatSetParameters:
5989        case kWhatShutdown:
5990        {
5991            mCodec->deferMessage(msg);
5992            return true;
5993        }
5994
5995        case kWhatResume:
5996        {
5997            // We'll be active soon enough.
5998            return true;
5999        }
6000
6001        case kWhatFlush:
6002        {
6003            // We haven't even started yet, so we're flushed alright...
6004            sp<AMessage> notify = mCodec->mNotify->dup();
6005            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
6006            notify->post();
6007
6008            return true;
6009        }
6010
6011        case kWhatSignalEndOfInputStream:
6012        {
6013            mCodec->onSignalEndOfInputStream();
6014            return true;
6015        }
6016
6017        default:
6018            return BaseState::onMessageReceived(msg);
6019    }
6020}
6021
6022bool ACodec::IdleToExecutingState::onOMXEvent(
6023        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6024    switch (event) {
6025        case OMX_EventCmdComplete:
6026        {
6027            if (data1 != (OMX_U32)OMX_CommandStateSet
6028                    || data2 != (OMX_U32)OMX_StateExecuting) {
6029                ALOGE("Unexpected command completion in IdleToExecutingState: %s(%u) %s(%u)",
6030                        asString((OMX_COMMANDTYPE)data1), data1,
6031                        asString((OMX_STATETYPE)data2), data2);
6032                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
6033                return true;
6034            }
6035
6036            mCodec->mExecutingState->resume();
6037            mCodec->changeState(mCodec->mExecutingState);
6038
6039            return true;
6040        }
6041
6042        default:
6043            return BaseState::onOMXEvent(event, data1, data2);
6044    }
6045}
6046
6047////////////////////////////////////////////////////////////////////////////////
6048
6049ACodec::ExecutingState::ExecutingState(ACodec *codec)
6050    : BaseState(codec),
6051      mActive(false) {
6052}
6053
6054ACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
6055        OMX_U32 /* portIndex */) {
6056    return RESUBMIT_BUFFERS;
6057}
6058
6059void ACodec::ExecutingState::submitOutputMetaBuffers() {
6060    // submit as many buffers as there are input buffers with the codec
6061    // in case we are in port reconfiguring
6062    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
6063        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
6064
6065        if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) {
6066            if (mCodec->submitOutputMetadataBuffer() != OK)
6067                break;
6068        }
6069    }
6070
6071    // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
6072    mCodec->signalSubmitOutputMetadataBufferIfEOS_workaround();
6073}
6074
6075void ACodec::ExecutingState::submitRegularOutputBuffers() {
6076    bool failed = false;
6077    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
6078        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
6079
6080        if (mCodec->mNativeWindow != NULL) {
6081            if (info->mStatus != BufferInfo::OWNED_BY_US
6082                    && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
6083                ALOGE("buffers should be owned by us or the surface");
6084                failed = true;
6085                break;
6086            }
6087
6088            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
6089                continue;
6090            }
6091        } else {
6092            if (info->mStatus != BufferInfo::OWNED_BY_US) {
6093                ALOGE("buffers should be owned by us");
6094                failed = true;
6095                break;
6096            }
6097        }
6098
6099        ALOGV("[%s] calling fillBuffer %u", mCodec->mComponentName.c_str(), info->mBufferID);
6100
6101        info->checkWriteFence("submitRegularOutputBuffers");
6102        status_t err = mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID, info->mFenceFd);
6103        info->mFenceFd = -1;
6104        if (err != OK) {
6105            failed = true;
6106            break;
6107        }
6108
6109        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
6110    }
6111
6112    if (failed) {
6113        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
6114    }
6115}
6116
6117void ACodec::ExecutingState::submitOutputBuffers() {
6118    submitRegularOutputBuffers();
6119    if (mCodec->storingMetadataInDecodedBuffers()) {
6120        submitOutputMetaBuffers();
6121    }
6122}
6123
6124void ACodec::ExecutingState::resume() {
6125    if (mActive) {
6126        ALOGV("[%s] We're already active, no need to resume.", mCodec->mComponentName.c_str());
6127        return;
6128    }
6129
6130    submitOutputBuffers();
6131
6132    // Post all available input buffers
6133    if (mCodec->mBuffers[kPortIndexInput].size() == 0u) {
6134        ALOGW("[%s] we don't have any input buffers to resume", mCodec->mComponentName.c_str());
6135    }
6136
6137    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); i++) {
6138        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
6139        if (info->mStatus == BufferInfo::OWNED_BY_US) {
6140            postFillThisBuffer(info);
6141        }
6142    }
6143
6144    mActive = true;
6145}
6146
6147void ACodec::ExecutingState::stateEntered() {
6148    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
6149
6150    mCodec->mRenderTracker.clear(systemTime(CLOCK_MONOTONIC));
6151    mCodec->processDeferredMessages();
6152}
6153
6154bool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
6155    bool handled = false;
6156
6157    switch (msg->what()) {
6158        case kWhatShutdown:
6159        {
6160            int32_t keepComponentAllocated;
6161            CHECK(msg->findInt32(
6162                        "keepComponentAllocated", &keepComponentAllocated));
6163
6164            mCodec->mShutdownInProgress = true;
6165            mCodec->mExplicitShutdown = true;
6166            mCodec->mKeepComponentAllocated = keepComponentAllocated;
6167
6168            mActive = false;
6169
6170            status_t err = mCodec->mOMX->sendCommand(
6171                    mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle);
6172            if (err != OK) {
6173                if (keepComponentAllocated) {
6174                    mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
6175                }
6176                // TODO: do some recovery here.
6177            } else {
6178                mCodec->changeState(mCodec->mExecutingToIdleState);
6179            }
6180
6181            handled = true;
6182            break;
6183        }
6184
6185        case kWhatFlush:
6186        {
6187            ALOGV("[%s] ExecutingState flushing now "
6188                 "(codec owns %zu/%zu input, %zu/%zu output).",
6189                    mCodec->mComponentName.c_str(),
6190                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
6191                    mCodec->mBuffers[kPortIndexInput].size(),
6192                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
6193                    mCodec->mBuffers[kPortIndexOutput].size());
6194
6195            mActive = false;
6196
6197            status_t err = mCodec->mOMX->sendCommand(mCodec->mNode, OMX_CommandFlush, OMX_ALL);
6198            if (err != OK) {
6199                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
6200            } else {
6201                mCodec->changeState(mCodec->mFlushingState);
6202            }
6203
6204            handled = true;
6205            break;
6206        }
6207
6208        case kWhatResume:
6209        {
6210            resume();
6211
6212            handled = true;
6213            break;
6214        }
6215
6216        case kWhatRequestIDRFrame:
6217        {
6218            status_t err = mCodec->requestIDRFrame();
6219            if (err != OK) {
6220                ALOGW("Requesting an IDR frame failed.");
6221            }
6222
6223            handled = true;
6224            break;
6225        }
6226
6227        case kWhatSetParameters:
6228        {
6229            sp<AMessage> params;
6230            CHECK(msg->findMessage("params", &params));
6231
6232            status_t err = mCodec->setParameters(params);
6233
6234            sp<AMessage> reply;
6235            if (msg->findMessage("reply", &reply)) {
6236                reply->setInt32("err", err);
6237                reply->post();
6238            }
6239
6240            handled = true;
6241            break;
6242        }
6243
6244        case ACodec::kWhatSignalEndOfInputStream:
6245        {
6246            mCodec->onSignalEndOfInputStream();
6247            handled = true;
6248            break;
6249        }
6250
6251        // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
6252        case kWhatSubmitOutputMetadataBufferIfEOS:
6253        {
6254            if (mCodec->mPortEOS[kPortIndexInput] &&
6255                    !mCodec->mPortEOS[kPortIndexOutput]) {
6256                status_t err = mCodec->submitOutputMetadataBuffer();
6257                if (err == OK) {
6258                    mCodec->signalSubmitOutputMetadataBufferIfEOS_workaround();
6259                }
6260            }
6261            return true;
6262        }
6263
6264        default:
6265            handled = BaseState::onMessageReceived(msg);
6266            break;
6267    }
6268
6269    return handled;
6270}
6271
6272status_t ACodec::setParameters(const sp<AMessage> &params) {
6273    int32_t videoBitrate;
6274    if (params->findInt32("video-bitrate", &videoBitrate)) {
6275        OMX_VIDEO_CONFIG_BITRATETYPE configParams;
6276        InitOMXParams(&configParams);
6277        configParams.nPortIndex = kPortIndexOutput;
6278        configParams.nEncodeBitrate = videoBitrate;
6279
6280        status_t err = mOMX->setConfig(
6281                mNode,
6282                OMX_IndexConfigVideoBitrate,
6283                &configParams,
6284                sizeof(configParams));
6285
6286        if (err != OK) {
6287            ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
6288                   videoBitrate, err);
6289
6290            return err;
6291        }
6292    }
6293
6294    int64_t skipFramesBeforeUs;
6295    if (params->findInt64("skip-frames-before", &skipFramesBeforeUs)) {
6296        status_t err =
6297            mOMX->setInternalOption(
6298                     mNode,
6299                     kPortIndexInput,
6300                     IOMX::INTERNAL_OPTION_START_TIME,
6301                     &skipFramesBeforeUs,
6302                     sizeof(skipFramesBeforeUs));
6303
6304        if (err != OK) {
6305            ALOGE("Failed to set parameter 'skip-frames-before' (err %d)", err);
6306            return err;
6307        }
6308    }
6309
6310    int32_t dropInputFrames;
6311    if (params->findInt32("drop-input-frames", &dropInputFrames)) {
6312        bool suspend = dropInputFrames != 0;
6313
6314        status_t err =
6315            mOMX->setInternalOption(
6316                     mNode,
6317                     kPortIndexInput,
6318                     IOMX::INTERNAL_OPTION_SUSPEND,
6319                     &suspend,
6320                     sizeof(suspend));
6321
6322        if (err != OK) {
6323            ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err);
6324            return err;
6325        }
6326    }
6327
6328    int32_t dummy;
6329    if (params->findInt32("request-sync", &dummy)) {
6330        status_t err = requestIDRFrame();
6331
6332        if (err != OK) {
6333            ALOGE("Requesting a sync frame failed w/ err %d", err);
6334            return err;
6335        }
6336    }
6337
6338    float rate;
6339    if (params->findFloat("operating-rate", &rate) && rate > 0) {
6340        status_t err = setOperatingRate(rate, mIsVideo);
6341        if (err != OK) {
6342            ALOGE("Failed to set parameter 'operating-rate' (err %d)", err);
6343            return err;
6344        }
6345    }
6346
6347    return OK;
6348}
6349
6350void ACodec::onSignalEndOfInputStream() {
6351    sp<AMessage> notify = mNotify->dup();
6352    notify->setInt32("what", CodecBase::kWhatSignaledInputEOS);
6353
6354    status_t err = mOMX->signalEndOfInputStream(mNode);
6355    if (err != OK) {
6356        notify->setInt32("err", err);
6357    }
6358    notify->post();
6359}
6360
6361bool ACodec::ExecutingState::onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano) {
6362    mCodec->onFrameRendered(mediaTimeUs, systemNano);
6363    return true;
6364}
6365
6366bool ACodec::ExecutingState::onOMXEvent(
6367        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6368    switch (event) {
6369        case OMX_EventPortSettingsChanged:
6370        {
6371            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
6372
6373            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
6374                mCodec->mMetadataBuffersToSubmit = 0;
6375                CHECK_EQ(mCodec->mOMX->sendCommand(
6376                            mCodec->mNode,
6377                            OMX_CommandPortDisable, kPortIndexOutput),
6378                         (status_t)OK);
6379
6380                mCodec->freeOutputBuffersNotOwnedByComponent();
6381
6382                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
6383            } else if (data2 == OMX_IndexConfigCommonOutputCrop) {
6384                mCodec->mSentFormat = false;
6385
6386                if (mCodec->mTunneled) {
6387                    sp<AMessage> dummy = new AMessage(kWhatOutputBufferDrained, mCodec);
6388                    mCodec->sendFormatChange(dummy);
6389                }
6390            } else {
6391                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08x",
6392                     mCodec->mComponentName.c_str(), data2);
6393            }
6394
6395            return true;
6396        }
6397
6398        case OMX_EventBufferFlag:
6399        {
6400            return true;
6401        }
6402
6403        default:
6404            return BaseState::onOMXEvent(event, data1, data2);
6405    }
6406}
6407
6408////////////////////////////////////////////////////////////////////////////////
6409
6410ACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
6411        ACodec *codec)
6412    : BaseState(codec) {
6413}
6414
6415ACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
6416        OMX_U32 portIndex) {
6417    if (portIndex == kPortIndexOutput) {
6418        return FREE_BUFFERS;
6419    }
6420
6421    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
6422
6423    return RESUBMIT_BUFFERS;
6424}
6425
6426bool ACodec::OutputPortSettingsChangedState::onMessageReceived(
6427        const sp<AMessage> &msg) {
6428    bool handled = false;
6429
6430    switch (msg->what()) {
6431        case kWhatFlush:
6432        case kWhatShutdown:
6433        case kWhatResume:
6434        case kWhatSetParameters:
6435        {
6436            if (msg->what() == kWhatResume) {
6437                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
6438            }
6439
6440            mCodec->deferMessage(msg);
6441            handled = true;
6442            break;
6443        }
6444
6445        default:
6446            handled = BaseState::onMessageReceived(msg);
6447            break;
6448    }
6449
6450    return handled;
6451}
6452
6453void ACodec::OutputPortSettingsChangedState::stateEntered() {
6454    ALOGV("[%s] Now handling output port settings change",
6455         mCodec->mComponentName.c_str());
6456}
6457
6458bool ACodec::OutputPortSettingsChangedState::onOMXFrameRendered(
6459        int64_t mediaTimeUs, nsecs_t systemNano) {
6460    mCodec->onFrameRendered(mediaTimeUs, systemNano);
6461    return true;
6462}
6463
6464bool ACodec::OutputPortSettingsChangedState::onOMXEvent(
6465        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6466    switch (event) {
6467        case OMX_EventCmdComplete:
6468        {
6469            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
6470                if (data2 != (OMX_U32)kPortIndexOutput) {
6471                    ALOGW("ignoring EventCmdComplete CommandPortDisable for port %u", data2);
6472                    return false;
6473                }
6474
6475                ALOGV("[%s] Output port now disabled.", mCodec->mComponentName.c_str());
6476
6477                status_t err = OK;
6478                if (!mCodec->mBuffers[kPortIndexOutput].isEmpty()) {
6479                    ALOGE("disabled port should be empty, but has %zu buffers",
6480                            mCodec->mBuffers[kPortIndexOutput].size());
6481                    err = FAILED_TRANSACTION;
6482                } else {
6483                    mCodec->mDealer[kPortIndexOutput].clear();
6484                }
6485
6486                if (err == OK) {
6487                    err = mCodec->mOMX->sendCommand(
6488                            mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput);
6489                }
6490
6491                if (err == OK) {
6492                    err = mCodec->allocateBuffersOnPort(kPortIndexOutput);
6493                    ALOGE_IF(err != OK, "Failed to allocate output port buffers after port "
6494                            "reconfiguration: (%d)", err);
6495                }
6496
6497                if (err != OK) {
6498                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
6499
6500                    // This is technically not correct, but appears to be
6501                    // the only way to free the component instance.
6502                    // Controlled transitioning from excecuting->idle
6503                    // and idle->loaded seem impossible probably because
6504                    // the output port never finishes re-enabling.
6505                    mCodec->mShutdownInProgress = true;
6506                    mCodec->mKeepComponentAllocated = false;
6507                    mCodec->changeState(mCodec->mLoadedState);
6508                }
6509
6510                return true;
6511            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
6512                if (data2 != (OMX_U32)kPortIndexOutput) {
6513                    ALOGW("ignoring EventCmdComplete OMX_CommandPortEnable for port %u", data2);
6514                    return false;
6515                }
6516
6517                mCodec->mSentFormat = false;
6518
6519                if (mCodec->mTunneled) {
6520                    sp<AMessage> dummy = new AMessage(kWhatOutputBufferDrained, mCodec);
6521                    mCodec->sendFormatChange(dummy);
6522                }
6523
6524                ALOGV("[%s] Output port now reenabled.", mCodec->mComponentName.c_str());
6525
6526                if (mCodec->mExecutingState->active()) {
6527                    mCodec->mExecutingState->submitOutputBuffers();
6528                }
6529
6530                mCodec->changeState(mCodec->mExecutingState);
6531
6532                return true;
6533            }
6534
6535            return false;
6536        }
6537
6538        default:
6539            return false;
6540    }
6541}
6542
6543////////////////////////////////////////////////////////////////////////////////
6544
6545ACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
6546    : BaseState(codec),
6547      mComponentNowIdle(false) {
6548}
6549
6550bool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
6551    bool handled = false;
6552
6553    switch (msg->what()) {
6554        case kWhatFlush:
6555        {
6556            // Don't send me a flush request if you previously wanted me
6557            // to shutdown.
6558            ALOGW("Ignoring flush request in ExecutingToIdleState");
6559            break;
6560        }
6561
6562        case kWhatShutdown:
6563        {
6564            // We're already doing that...
6565
6566            handled = true;
6567            break;
6568        }
6569
6570        default:
6571            handled = BaseState::onMessageReceived(msg);
6572            break;
6573    }
6574
6575    return handled;
6576}
6577
6578void ACodec::ExecutingToIdleState::stateEntered() {
6579    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
6580
6581    mComponentNowIdle = false;
6582    mCodec->mSentFormat = false;
6583}
6584
6585bool ACodec::ExecutingToIdleState::onOMXEvent(
6586        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6587    switch (event) {
6588        case OMX_EventCmdComplete:
6589        {
6590            if (data1 != (OMX_U32)OMX_CommandStateSet
6591                    || data2 != (OMX_U32)OMX_StateIdle) {
6592                ALOGE("Unexpected command completion in ExecutingToIdleState: %s(%u) %s(%u)",
6593                        asString((OMX_COMMANDTYPE)data1), data1,
6594                        asString((OMX_STATETYPE)data2), data2);
6595                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
6596                return true;
6597            }
6598
6599            mComponentNowIdle = true;
6600
6601            changeStateIfWeOwnAllBuffers();
6602
6603            return true;
6604        }
6605
6606        case OMX_EventPortSettingsChanged:
6607        case OMX_EventBufferFlag:
6608        {
6609            // We're shutting down and don't care about this anymore.
6610            return true;
6611        }
6612
6613        default:
6614            return BaseState::onOMXEvent(event, data1, data2);
6615    }
6616}
6617
6618void ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
6619    if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
6620        status_t err = mCodec->mOMX->sendCommand(
6621                mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded);
6622        if (err == OK) {
6623            err = mCodec->freeBuffersOnPort(kPortIndexInput);
6624            status_t err2 = mCodec->freeBuffersOnPort(kPortIndexOutput);
6625            if (err == OK) {
6626                err = err2;
6627            }
6628        }
6629
6630        if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown)
6631                && mCodec->mNativeWindow != NULL) {
6632            // We push enough 1x1 blank buffers to ensure that one of
6633            // them has made it to the display.  This allows the OMX
6634            // component teardown to zero out any protected buffers
6635            // without the risk of scanning out one of those buffers.
6636            pushBlankBuffersToNativeWindow(mCodec->mNativeWindow.get());
6637        }
6638
6639        if (err != OK) {
6640            mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
6641            return;
6642        }
6643
6644        mCodec->changeState(mCodec->mIdleToLoadedState);
6645    }
6646}
6647
6648void ACodec::ExecutingToIdleState::onInputBufferFilled(
6649        const sp<AMessage> &msg) {
6650    BaseState::onInputBufferFilled(msg);
6651
6652    changeStateIfWeOwnAllBuffers();
6653}
6654
6655void ACodec::ExecutingToIdleState::onOutputBufferDrained(
6656        const sp<AMessage> &msg) {
6657    BaseState::onOutputBufferDrained(msg);
6658
6659    changeStateIfWeOwnAllBuffers();
6660}
6661
6662////////////////////////////////////////////////////////////////////////////////
6663
6664ACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
6665    : BaseState(codec) {
6666}
6667
6668bool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
6669    bool handled = false;
6670
6671    switch (msg->what()) {
6672        case kWhatShutdown:
6673        {
6674            // We're already doing that...
6675
6676            handled = true;
6677            break;
6678        }
6679
6680        case kWhatFlush:
6681        {
6682            // Don't send me a flush request if you previously wanted me
6683            // to shutdown.
6684            ALOGE("Got flush request in IdleToLoadedState");
6685            break;
6686        }
6687
6688        default:
6689            handled = BaseState::onMessageReceived(msg);
6690            break;
6691    }
6692
6693    return handled;
6694}
6695
6696void ACodec::IdleToLoadedState::stateEntered() {
6697    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
6698}
6699
6700bool ACodec::IdleToLoadedState::onOMXEvent(
6701        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6702    switch (event) {
6703        case OMX_EventCmdComplete:
6704        {
6705            if (data1 != (OMX_U32)OMX_CommandStateSet
6706                    || data2 != (OMX_U32)OMX_StateLoaded) {
6707                ALOGE("Unexpected command completion in IdleToLoadedState: %s(%u) %s(%u)",
6708                        asString((OMX_COMMANDTYPE)data1), data1,
6709                        asString((OMX_STATETYPE)data2), data2);
6710                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
6711                return true;
6712            }
6713
6714            mCodec->changeState(mCodec->mLoadedState);
6715
6716            return true;
6717        }
6718
6719        default:
6720            return BaseState::onOMXEvent(event, data1, data2);
6721    }
6722}
6723
6724////////////////////////////////////////////////////////////////////////////////
6725
6726ACodec::FlushingState::FlushingState(ACodec *codec)
6727    : BaseState(codec) {
6728}
6729
6730void ACodec::FlushingState::stateEntered() {
6731    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
6732
6733    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
6734}
6735
6736bool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
6737    bool handled = false;
6738
6739    switch (msg->what()) {
6740        case kWhatShutdown:
6741        {
6742            mCodec->deferMessage(msg);
6743            break;
6744        }
6745
6746        case kWhatFlush:
6747        {
6748            // We're already doing this right now.
6749            handled = true;
6750            break;
6751        }
6752
6753        default:
6754            handled = BaseState::onMessageReceived(msg);
6755            break;
6756    }
6757
6758    return handled;
6759}
6760
6761bool ACodec::FlushingState::onOMXEvent(
6762        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6763    ALOGV("[%s] FlushingState onOMXEvent(%u,%d)",
6764            mCodec->mComponentName.c_str(), event, (OMX_S32)data1);
6765
6766    switch (event) {
6767        case OMX_EventCmdComplete:
6768        {
6769            if (data1 != (OMX_U32)OMX_CommandFlush) {
6770                ALOGE("unexpected EventCmdComplete %s(%d) data2:%d in FlushingState",
6771                        asString((OMX_COMMANDTYPE)data1), data1, data2);
6772                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
6773                return true;
6774            }
6775
6776            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
6777                if (mFlushComplete[data2]) {
6778                    ALOGW("Flush already completed for %s port",
6779                            data2 == kPortIndexInput ? "input" : "output");
6780                    return true;
6781                }
6782                mFlushComplete[data2] = true;
6783
6784                if (mFlushComplete[kPortIndexInput] && mFlushComplete[kPortIndexOutput]) {
6785                    changeStateIfWeOwnAllBuffers();
6786                }
6787            } else if (data2 == OMX_ALL) {
6788                if (!mFlushComplete[kPortIndexInput] || !mFlushComplete[kPortIndexOutput]) {
6789                    ALOGW("received flush complete event for OMX_ALL before ports have been"
6790                            "flushed (%d/%d)",
6791                            mFlushComplete[kPortIndexInput], mFlushComplete[kPortIndexOutput]);
6792                    return false;
6793                }
6794
6795                changeStateIfWeOwnAllBuffers();
6796            } else {
6797                ALOGW("data2 not OMX_ALL but %u in EventCmdComplete CommandFlush", data2);
6798            }
6799
6800            return true;
6801        }
6802
6803        case OMX_EventPortSettingsChanged:
6804        {
6805            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec);
6806            msg->setInt32("type", omx_message::EVENT);
6807            msg->setInt32("node", mCodec->mNode);
6808            msg->setInt32("event", event);
6809            msg->setInt32("data1", data1);
6810            msg->setInt32("data2", data2);
6811
6812            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
6813                 mCodec->mComponentName.c_str());
6814
6815            mCodec->deferMessage(msg);
6816
6817            return true;
6818        }
6819
6820        default:
6821            return BaseState::onOMXEvent(event, data1, data2);
6822    }
6823
6824    return true;
6825}
6826
6827void ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
6828    BaseState::onOutputBufferDrained(msg);
6829
6830    changeStateIfWeOwnAllBuffers();
6831}
6832
6833void ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
6834    BaseState::onInputBufferFilled(msg);
6835
6836    changeStateIfWeOwnAllBuffers();
6837}
6838
6839void ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
6840    if (mFlushComplete[kPortIndexInput]
6841            && mFlushComplete[kPortIndexOutput]
6842            && mCodec->allYourBuffersAreBelongToUs()) {
6843        // We now own all buffers except possibly those still queued with
6844        // the native window for rendering. Let's get those back as well.
6845        mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
6846
6847        mCodec->mRenderTracker.clear(systemTime(CLOCK_MONOTONIC));
6848
6849        sp<AMessage> notify = mCodec->mNotify->dup();
6850        notify->setInt32("what", CodecBase::kWhatFlushCompleted);
6851        notify->post();
6852
6853        mCodec->mPortEOS[kPortIndexInput] =
6854            mCodec->mPortEOS[kPortIndexOutput] = false;
6855
6856        mCodec->mInputEOSResult = OK;
6857
6858        if (mCodec->mSkipCutBuffer != NULL) {
6859            mCodec->mSkipCutBuffer->clear();
6860        }
6861
6862        mCodec->changeState(mCodec->mExecutingState);
6863    }
6864}
6865
6866}  // namespace android
6867