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