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