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