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