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