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