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