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